xref: /openbsd-src/sys/dev/acpi/dsdt.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /* $OpenBSD: dsdt.c,v 1.191 2011/06/15 08:11:51 pirofti Exp $ */
2 /*
3  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/kernel.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23 #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 int64_t			aml_evalexpr(int64_t, 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 int64_t
1103 aml_evalexpr(int64_t lhs, int64_t rhs, int opcode)
1104 {
1105 	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, int mode, int flag)
2229 {
2230 	struct aml_value tmp;
2231 	union amlpci_t pi;
2232 	void *tbit, *vbit;
2233 	int slen, type, sz;
2234 
2235 	dnprintf(10," %5s %.2x %.8llx %.4x [%s]\n",
2236 		mode == ACPI_IOREAD ? "read" : "write",
2237 		rgn->v_opregion.iospace,
2238 		rgn->v_opregion.iobase + (bpos >> 3),
2239 		blen, aml_nodename(rgn->node));
2240 	memset(&tmp, 0, sizeof(tmp));
2241 	pi.addr = rgn->v_opregion.iobase + (bpos >> 3);
2242 	if (rgn->v_opregion.iospace == GAS_PCI_CFG_SPACE)
2243 	{
2244 		/* Get PCI Root Address for this opregion */
2245 		aml_rdpciaddr(rgn->node->parent, &pi);
2246 	}
2247 
2248 	/* Get field access size */
2249 	switch (AML_FIELD_ACCESS(flag)) {
2250 	case AML_FIELD_WORDACC:
2251 		sz = 2;
2252 		break;
2253 	case AML_FIELD_DWORDACC:
2254 		sz = 4;
2255 		break;
2256 	case AML_FIELD_QWORDACC:
2257 		sz = 8;
2258 		break;
2259 	default:
2260 		sz = 1;
2261 		break;
2262 	}
2263 
2264 	tbit = &tmp.v_integer;
2265 	vbit = &val->v_integer;
2266 	slen = (blen + 7) >> 3;
2267 	type = rgn->v_opregion.iospace;
2268 
2269 	/* Allocate temporary storage */
2270 	if (blen > aml_intlen) {
2271 		if (mode == ACPI_IOREAD) {
2272 			/* Read from a large field:  create buffer */
2273 			_aml_setvalue(val, AML_OBJTYPE_BUFFER, slen, 0);
2274 		} else {
2275 			/* Write to a large field.. create or convert buffer */
2276 			val = aml_convert(val, AML_OBJTYPE_BUFFER, -1);
2277 		}
2278 		_aml_setvalue(&tmp, AML_OBJTYPE_BUFFER, slen, 0);
2279 		tbit = tmp.v_buffer;
2280 		vbit = val->v_buffer;
2281 	} else if (mode == ACPI_IOREAD) {
2282 		/* Read from a short field.. initialize integer */
2283 		_aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2284 	} else {
2285 		/* Write to a short field.. convert to integer */
2286 		val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
2287 	}
2288 
2289 	if (mode == ACPI_IOREAD) {
2290 		/* Read bits from opregion */
2291 		acpi_gasio(acpi_softc, ACPI_IOREAD, type, pi.addr, sz, slen, tbit);
2292 		aml_bufcpy(vbit, 0, tbit, bpos & 7, blen);
2293 	} else {
2294 		/* Write bits to opregion */
2295 		if (val->length < slen) {
2296 			dnprintf(0,"writetooshort: %d %d %s\n", val->length, slen, aml_nodename(rgn->node));
2297 			slen = val->length;
2298 		}
2299 		if (AML_FIELD_UPDATE(flag) == AML_FIELD_PRESERVE && ((bpos|blen) & 7)) {
2300 			/* If not aligned and preserve, read existing value */
2301 			acpi_gasio(acpi_softc, ACPI_IOREAD, type, pi.addr, sz, slen, tbit);
2302 		} else if (AML_FIELD_UPDATE(flag) == AML_FIELD_WRITEASONES) {
2303 			memset(tbit, 0xFF, tmp.length);
2304 		}
2305 		/* Copy target bits, then write to region */
2306 		aml_bufcpy(tbit, bpos & 7, vbit, 0, blen);
2307 		acpi_gasio(acpi_softc, ACPI_IOWRITE, type, pi.addr, sz, slen, tbit);
2308 
2309 		aml_delref(&val, "fld.write");
2310 	}
2311 	aml_freevalue(&tmp);
2312 }
2313 
2314 void
2315 aml_rwfield(struct aml_value *fld, int bpos, int blen, struct aml_value *val, int mode)
2316 {
2317 	struct aml_value tmp, *ref1, *ref2;
2318 
2319 	ref2 = fld->v_field.ref2;
2320 	ref1 = fld->v_field.ref1;
2321 	if (blen > fld->v_field.bitlen)
2322 		blen = fld->v_field.bitlen;
2323 
2324 	aml_lockfield(NULL, fld);
2325 	memset(&tmp, 0, sizeof(tmp));
2326 	aml_addref(&tmp, "fld.write");
2327 	if (fld->v_field.type == AMLOP_INDEXFIELD) {
2328 		_aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field.ref3, 0);
2329 		aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE);
2330 		aml_rwfield(ref1, fld->v_field.bitpos, fld->v_field.bitlen, val, mode);
2331 	} else if (fld->v_field.type == AMLOP_BANKFIELD) {
2332 		_aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field.ref3, 0);
2333 		aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE);
2334 		aml_rwgas(ref1, fld->v_field.bitpos, fld->v_field.bitlen, val, mode, fld->v_field.flags);
2335 	} else if (fld->v_field.type == AMLOP_FIELD) {
2336 		aml_rwgas(ref1, fld->v_field.bitpos+bpos, blen, val, mode, fld->v_field.flags);
2337 	} else if (mode == ACPI_IOREAD) {
2338 		/* bufferfield:read */
2339 		_aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2340 		aml_bufcpy(&val->v_integer, 0, ref1->v_buffer, fld->v_field.bitpos, fld->v_field.bitlen);
2341 	} else {
2342 		/* bufferfield:write */
2343 		val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
2344 		aml_bufcpy(ref1->v_buffer, fld->v_field.bitpos, &val->v_integer, 0, fld->v_field.bitlen);
2345 		aml_delref(&val, "wrbuffld");
2346 	}
2347 	aml_unlockfield(NULL, fld);
2348 }
2349 
2350 /* Create Field Object          data		index
2351  *   AMLOP_FIELD		n:OpRegion	NULL
2352  *   AMLOP_INDEXFIELD		n:Field		n:Field
2353  *   AMLOP_BANKFIELD		n:OpRegion	n:Field
2354  *   AMLOP_CREATEFIELD		t:Buffer	NULL
2355  *   AMLOP_CREATEBITFIELD	t:Buffer	NULL
2356  *   AMLOP_CREATEBYTEFIELD	t:Buffer	NULL
2357  *   AMLOP_CREATEWORDFIELD	t:Buffer	NULL
2358  *   AMLOP_CREATEDWORDFIELD	t:Buffer	NULL
2359  *   AMLOP_CREATEQWORDFIELD	t:Buffer	NULL
2360  *   AMLOP_INDEX		t:Buffer	NULL
2361  */
2362 void
2363 aml_createfield(struct aml_value *field, int opcode,
2364 		struct aml_value *data, int bpos, int blen,
2365 		struct aml_value *index, int indexval, int flags)
2366 {
2367 	dnprintf(10, "## %s(%s): %s %.4x-%.4x\n",
2368 	    aml_mnem(opcode, 0),
2369 	    blen > aml_intlen ? "BUF" : "INT",
2370 	    aml_nodename(field->node), bpos, blen);
2371 	if (index) {
2372 		dnprintf(10, "  index:%s:%.2x\n", aml_nodename(index->node),
2373 		    indexval);
2374 	}
2375 	dnprintf(10, "  data:%s\n", aml_nodename(data->node));
2376 	field->type = (opcode == AMLOP_FIELD ||
2377 	    opcode == AMLOP_INDEXFIELD ||
2378 	    opcode == AMLOP_BANKFIELD) ?
2379 	    AML_OBJTYPE_FIELDUNIT :
2380 	    AML_OBJTYPE_BUFFERFIELD;
2381 	if (opcode == AMLOP_INDEXFIELD) {
2382 		indexval = bpos >> 3;
2383 		bpos &= 7;
2384 	}
2385 
2386 	if (field->type == AML_OBJTYPE_BUFFERFIELD &&
2387 	    data->type != AML_OBJTYPE_BUFFER)
2388 		data = aml_convert(data, AML_OBJTYPE_BUFFER, -1);
2389 
2390 	field->v_field.type = opcode;
2391 	field->v_field.bitpos = bpos;
2392 	field->v_field.bitlen = blen;
2393 	field->v_field.ref3 = indexval;
2394 	field->v_field.ref2 = index;
2395 	field->v_field.ref1 = data;
2396 	field->v_field.flags = flags;
2397 
2398 	/* Increase reference count */
2399 	aml_addref(data, "Field.Data");
2400 	aml_addref(index, "Field.Index");
2401 }
2402 
2403 /* Parse Field/IndexField/BankField scope */
2404 void
2405 aml_parsefieldlist(struct aml_scope *mscope, int opcode, int flags,
2406     struct aml_value *data, struct aml_value *index, int indexval)
2407 {
2408 	struct aml_value *rv;
2409 	int bpos, blen;
2410 
2411 	if (mscope == NULL)
2412 		return;
2413 	bpos = 0;
2414 	while (mscope->pos < mscope->end) {
2415 		switch (*mscope->pos) {
2416 		case 0x00: // reserved, length
2417 			mscope->pos++;
2418 			blen = aml_parselength(mscope);
2419 			break;
2420 		case 0x01: // flags
2421 			mscope->pos += 3;
2422 			blen = 0;
2423 			break;
2424 		default: // 4-byte name, length
2425 			mscope->pos = aml_parsename(mscope->node, mscope->pos,
2426 			    &rv, 1);
2427 			blen = aml_parselength(mscope);
2428 			aml_createfield(rv, opcode, data, bpos, blen, index,
2429 				indexval, flags);
2430 			aml_delref(&rv, 0);
2431 			break;
2432 		}
2433 		bpos += blen;
2434 	}
2435 	aml_popscope(mscope);
2436 }
2437 
2438 /*
2439  * Mutex/Event utility functions
2440  */
2441 int	acpi_mutex_acquire(struct aml_scope *, struct aml_value *, int);
2442 void	acpi_mutex_release(struct aml_scope *, struct aml_value *);
2443 int	acpi_event_wait(struct aml_scope *, struct aml_value *, int);
2444 void	acpi_event_signal(struct aml_scope *, struct aml_value *);
2445 void	acpi_event_reset(struct aml_scope *, struct aml_value *);
2446 
2447 int
2448 acpi_mutex_acquire(struct aml_scope *scope, struct aml_value *mtx,
2449     int timeout)
2450 {
2451 	int err;
2452 
2453 	if (mtx->v_mtx.owner == NULL || scope == mtx->v_mtx.owner) {
2454 		/* We are now the owner */
2455 		mtx->v_mtx.owner = scope;
2456 		if (mtx == aml_global_lock) {
2457 			dnprintf(10,"LOCKING GLOBAL\n");
2458 			err = acpi_acquire_global_lock(&acpi_softc->sc_facs->global_lock);
2459 		}
2460 		dnprintf(5,"%s acquires mutex %s\n", scope->node->name,
2461 		    mtx->node->name);
2462 		return (0);
2463 	} else if (timeout == 0) {
2464 		return (-1);
2465 	}
2466 	/* Wait for mutex */
2467 	return (0);
2468 }
2469 
2470 void
2471 acpi_mutex_release(struct aml_scope *scope, struct aml_value *mtx)
2472 {
2473 	int err;
2474 
2475 	if (mtx == aml_global_lock) {
2476 		dnprintf(10,"UNLOCKING GLOBAL\n");
2477 		err=acpi_release_global_lock(&acpi_softc->sc_facs->global_lock);
2478 	}
2479 	dnprintf(5, "%s releases mutex %s\n", scope->node->name,
2480 	    mtx->node->name);
2481 	mtx->v_mtx.owner = NULL;
2482 	/* Wakeup waiters */
2483 }
2484 
2485 int
2486 acpi_event_wait(struct aml_scope *scope, struct aml_value *evt, int timeout)
2487 {
2488 	/* Wait for event to occur; do work in meantime */
2489 	evt->v_evt.state = 0;
2490 	while (!evt->v_evt.state) {
2491 		if (!acpi_dotask(acpi_softc) && !cold)
2492 			tsleep(evt, PWAIT, "acpievt", 1);
2493 		else
2494 			delay(100);
2495 	}
2496 	if (evt->v_evt.state == 1) {
2497 		/* Object is signaled */
2498 		return (0);
2499 	} else if (timeout == 0) {
2500 		/* Zero timeout */
2501 		return (-1);
2502 	}
2503 	/* Wait for timeout or signal */
2504 	return (0);
2505 }
2506 
2507 void
2508 acpi_event_signal(struct aml_scope *scope, struct aml_value *evt)
2509 {
2510 	evt->v_evt.state = 1;
2511 	/* Wakeup waiters */
2512 }
2513 
2514 void
2515 acpi_event_reset(struct aml_scope *scope, struct aml_value *evt)
2516 {
2517 	evt->v_evt.state = 0;
2518 }
2519 
2520 /* Store result value into an object */
2521 void
2522 aml_store(struct aml_scope *scope, struct aml_value *lhs , int64_t ival,
2523     struct aml_value *rhs)
2524 {
2525 	struct aml_value tmp;
2526 	int mlen;
2527 
2528 	/* Already set */
2529 	if (lhs == rhs || lhs == NULL || lhs->type == AML_OBJTYPE_NOTARGET) {
2530 		return;
2531 	}
2532 	memset(&tmp, 0, sizeof(tmp));
2533 	tmp.refcnt=99;
2534 	if (rhs == NULL) {
2535 		rhs = _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, ival, NULL);
2536 	}
2537 	if (rhs->type == AML_OBJTYPE_BUFFERFIELD ||
2538 	    rhs->type == AML_OBJTYPE_FIELDUNIT) {
2539 		aml_rwfield(rhs, 0, rhs->v_field.bitlen, &tmp, ACPI_IOREAD);
2540 		rhs = &tmp;
2541 	}
2542 	/* Store to LocalX: free value */
2543 	if (lhs->stack >= AMLOP_LOCAL0 && lhs->stack <= AMLOP_LOCAL7)
2544 		aml_freevalue(lhs);
2545 
2546 	lhs = aml_gettgt(lhs, AMLOP_STORE);
2547 	switch (lhs->type) {
2548 	case AML_OBJTYPE_UNINITIALIZED:
2549 		aml_copyvalue(lhs, rhs);
2550 		break;
2551 	case AML_OBJTYPE_BUFFERFIELD:
2552 	case AML_OBJTYPE_FIELDUNIT:
2553 		aml_rwfield(lhs, 0, lhs->v_field.bitlen, rhs, ACPI_IOWRITE);
2554 		break;
2555 	case AML_OBJTYPE_DEBUGOBJ:
2556 		break;
2557 	case AML_OBJTYPE_INTEGER:
2558 		rhs = aml_convert(rhs, lhs->type, -1);
2559 		lhs->v_integer = rhs->v_integer;
2560 		aml_delref(&rhs, "store.int");
2561 		break;
2562 	case AML_OBJTYPE_BUFFER:
2563 	case AML_OBJTYPE_STRING:
2564 		rhs = aml_convert(rhs, lhs->type, -1);
2565 		if (lhs->length < rhs->length) {
2566 			dnprintf(10,"Overrun! %d,%d\n", lhs->length, rhs->length);
2567 			aml_freevalue(lhs);
2568 			_aml_setvalue(lhs, rhs->type, rhs->length, NULL);
2569 		}
2570 		mlen = min(lhs->length, rhs->length);
2571 		memset(lhs->v_buffer, 0x00, lhs->length);
2572 		memcpy(lhs->v_buffer, rhs->v_buffer, mlen);
2573 		aml_delref(&rhs, "store.bufstr");
2574 		break;
2575 	case AML_OBJTYPE_PACKAGE:
2576 		/* Convert to LHS type, copy into LHS */
2577 		if (rhs->type != AML_OBJTYPE_PACKAGE) {
2578 			aml_die("Copy non-package into package?");
2579 		}
2580 		aml_freevalue(lhs);
2581 		aml_copyvalue(lhs, rhs);
2582 		break;
2583 	default:
2584 		aml_die("Store to default type!	 %x\n", lhs->type);
2585 		break;
2586 	}
2587 	aml_freevalue(&tmp);
2588 }
2589 
2590 #ifdef DDB
2591 /* Disassembler routines */
2592 void aml_disprintf(void *arg, const char *fmt, ...);
2593 
2594 void
2595 aml_disprintf(void *arg, const char *fmt, ...)
2596 {
2597 	va_list ap;
2598 
2599 	va_start(ap, fmt);
2600 	vprintf(fmt, ap);
2601 	va_end(ap);
2602 }
2603 
2604 void
2605 aml_disasm(struct aml_scope *scope, int lvl,
2606     void (*dbprintf)(void *, const char *, ...),
2607     void *arg)
2608 {
2609 	int pc, opcode;
2610 	struct aml_opcode *htab;
2611 	uint64_t ival;
2612 	struct aml_value *rv, tmp;
2613 	uint8_t *end = NULL;
2614 	struct aml_scope ms;
2615 	char *ch;
2616 	char  mch[64];
2617 
2618 	if (dbprintf == NULL)
2619 		dbprintf = aml_disprintf;
2620 
2621 	pc = aml_pc(scope->pos);
2622 	opcode = aml_parseopcode(scope);
2623 	htab = aml_findopcode(opcode);
2624 
2625 	/* Display address + indent */
2626 	if (lvl <= 0x7FFF) {
2627 		dbprintf(arg, "%.4x ", pc);
2628 		for (pc=0; pc<lvl; pc++) {
2629 			dbprintf(arg, "	 ");
2630 		}
2631 	}
2632 	ch = NULL;
2633 	switch (opcode) {
2634 	case AMLOP_NAMECHAR:
2635 		scope->pos = aml_parsename(scope->node, scope->pos, &rv, 0);
2636 		if (rv->type == AML_OBJTYPE_NAMEREF) {
2637 			ch = "@@@";
2638 			aml_delref(&rv, "disasm");
2639 			break;
2640 		}
2641 		/* if this is a method, get arguments */
2642 		strlcpy(mch, aml_nodename(rv->node), sizeof(mch));
2643 		if (rv->type == AML_OBJTYPE_METHOD) {
2644 			strlcat(mch, "(", sizeof(mch));
2645 			for (ival=0; ival<AML_METHOD_ARGCOUNT(rv->v_method.flags); ival++) {
2646 				strlcat(mch, ival ? ", %z" : "%z",
2647 				    sizeof(mch));
2648 			}
2649 			strlcat(mch, ")", sizeof(mch));
2650 		}
2651 		aml_delref(&rv, "");
2652 		ch = mch;
2653 		break;
2654 
2655 	case AMLOP_ZERO:
2656 	case AMLOP_ONE:
2657 	case AMLOP_ONES:
2658 	case AMLOP_LOCAL0:
2659 	case AMLOP_LOCAL1:
2660 	case AMLOP_LOCAL2:
2661 	case AMLOP_LOCAL3:
2662 	case AMLOP_LOCAL4:
2663 	case AMLOP_LOCAL5:
2664 	case AMLOP_LOCAL6:
2665 	case AMLOP_LOCAL7:
2666 	case AMLOP_ARG0:
2667 	case AMLOP_ARG1:
2668 	case AMLOP_ARG2:
2669 	case AMLOP_ARG3:
2670 	case AMLOP_ARG4:
2671 	case AMLOP_ARG5:
2672 	case AMLOP_ARG6:
2673 	case AMLOP_NOP:
2674 	case AMLOP_REVISION:
2675 	case AMLOP_DEBUG:
2676 	case AMLOP_CONTINUE:
2677 	case AMLOP_BREAKPOINT:
2678 	case AMLOP_BREAK:
2679 		ch="%m";
2680 		break;
2681 	case AMLOP_BYTEPREFIX:
2682 		ch="%b";
2683 		break;
2684 	case AMLOP_WORDPREFIX:
2685 		ch="%w";
2686 		break;
2687 	case AMLOP_DWORDPREFIX:
2688 		ch="%d";
2689 		break;
2690 	case AMLOP_QWORDPREFIX:
2691 		ch="%q";
2692 		break;
2693 	case AMLOP_STRINGPREFIX:
2694 		ch="%a";
2695 		break;
2696 
2697 	case AMLOP_INCREMENT:
2698 	case AMLOP_DECREMENT:
2699 	case AMLOP_LNOT:
2700 	case AMLOP_SIZEOF:
2701 	case AMLOP_DEREFOF:
2702 	case AMLOP_REFOF:
2703 	case AMLOP_OBJECTTYPE:
2704 	case AMLOP_UNLOAD:
2705 	case AMLOP_RELEASE:
2706 	case AMLOP_SIGNAL:
2707 	case AMLOP_RESET:
2708 	case AMLOP_STALL:
2709 	case AMLOP_SLEEP:
2710 	case AMLOP_RETURN:
2711 		ch="%m(%n)";
2712 		break;
2713 	case AMLOP_OR:
2714 	case AMLOP_ADD:
2715 	case AMLOP_AND:
2716 	case AMLOP_NAND:
2717 	case AMLOP_XOR:
2718 	case AMLOP_SHL:
2719 	case AMLOP_SHR:
2720 	case AMLOP_NOR:
2721 	case AMLOP_MOD:
2722 	case AMLOP_SUBTRACT:
2723 	case AMLOP_MULTIPLY:
2724 	case AMLOP_INDEX:
2725 	case AMLOP_CONCAT:
2726 	case AMLOP_CONCATRES:
2727 	case AMLOP_TOSTRING:
2728 		ch="%m(%n, %n, %n)";
2729 		break;
2730 	case AMLOP_CREATEBYTEFIELD:
2731 	case AMLOP_CREATEWORDFIELD:
2732 	case AMLOP_CREATEDWORDFIELD:
2733 	case AMLOP_CREATEQWORDFIELD:
2734 	case AMLOP_CREATEBITFIELD:
2735 		ch="%m(%n, %n, %N)";
2736 		break;
2737 	case AMLOP_CREATEFIELD:
2738 		ch="%m(%n, %n, %n, %N)";
2739 		break;
2740 	case AMLOP_DIVIDE:
2741 	case AMLOP_MID:
2742 		ch="%m(%n, %n, %n, %n)";
2743 		break;
2744 	case AMLOP_LAND:
2745 	case AMLOP_LOR:
2746 	case AMLOP_LNOTEQUAL:
2747 	case AMLOP_LLESSEQUAL:
2748 	case AMLOP_LLESS:
2749 	case AMLOP_LEQUAL:
2750 	case AMLOP_LGREATEREQUAL:
2751 	case AMLOP_LGREATER:
2752 	case AMLOP_NOT:
2753 	case AMLOP_FINDSETLEFTBIT:
2754 	case AMLOP_FINDSETRIGHTBIT:
2755 	case AMLOP_TOINTEGER:
2756 	case AMLOP_TOBUFFER:
2757 	case AMLOP_TOHEXSTRING:
2758 	case AMLOP_TODECSTRING:
2759 	case AMLOP_FROMBCD:
2760 	case AMLOP_TOBCD:
2761 	case AMLOP_WAIT:
2762 	case AMLOP_LOAD:
2763 	case AMLOP_STORE:
2764 	case AMLOP_NOTIFY:
2765 	case AMLOP_COPYOBJECT:
2766 		ch="%m(%n, %n)";
2767 		break;
2768 	case AMLOP_ACQUIRE:
2769 		ch = "%m(%n, %w)";
2770 		break;
2771 	case AMLOP_CONDREFOF:
2772 		ch="%m(%R, %n)";
2773 		break;
2774 	case AMLOP_ALIAS:
2775 		ch="%m(%n, %N)";
2776 		break;
2777 	case AMLOP_NAME:
2778 		ch="%m(%N, %n)";
2779 		break;
2780 	case AMLOP_EVENT:
2781 		ch="%m(%N)";
2782 		break;
2783 	case AMLOP_MUTEX:
2784 		ch = "%m(%N, %b)";
2785 		break;
2786 	case AMLOP_OPREGION:
2787 		ch = "%m(%N, %b, %n, %n)";
2788 		break;
2789 	case AMLOP_DATAREGION:
2790 		ch="%m(%N, %n, %n, %n)";
2791 		break;
2792 	case AMLOP_FATAL:
2793 		ch = "%m(%b, %d, %n)";
2794 		break;
2795 	case AMLOP_IF:
2796 	case AMLOP_WHILE:
2797 	case AMLOP_SCOPE:
2798 	case AMLOP_THERMALZONE:
2799 	case AMLOP_VARPACKAGE:
2800 		end = aml_parseend(scope);
2801 		ch = "%m(%n) {\n%T}";
2802 		break;
2803 	case AMLOP_DEVICE:
2804 		end = aml_parseend(scope);
2805 		ch = "%m(%N) {\n%T}";
2806 		break;
2807 	case AMLOP_POWERRSRC:
2808 		end = aml_parseend(scope);
2809 		ch = "%m(%N, %b, %w) {\n%T}";
2810 		break;
2811 	case AMLOP_PROCESSOR:
2812 		end = aml_parseend(scope);
2813 		ch = "%m(%N, %b, %d, %b) {\n%T}";
2814 		break;
2815 	case AMLOP_METHOD:
2816 		end = aml_parseend(scope);
2817 		ch = "%m(%N, %b) {\n%T}";
2818 		break;
2819 	case AMLOP_PACKAGE:
2820 		end = aml_parseend(scope);
2821 		ch = "%m(%b) {\n%T}";
2822 		break;
2823 	case AMLOP_ELSE:
2824 		end = aml_parseend(scope);
2825 		ch = "%m {\n%T}";
2826 		break;
2827 	case AMLOP_BUFFER:
2828 		end = aml_parseend(scope);
2829 		ch = "%m(%n) { %B }";
2830 		break;
2831 	case AMLOP_INDEXFIELD:
2832 		end = aml_parseend(scope);
2833 		ch = "%m(%n, %n, %b) {\n%F}";
2834 		break;
2835 	case AMLOP_BANKFIELD:
2836 		end = aml_parseend(scope);
2837 		ch = "%m(%n, %n, %n, %b) {\n%F}";
2838 		break;
2839 	case AMLOP_FIELD:
2840 		end = aml_parseend(scope);
2841 		ch = "%m(%n, %b) {\n%F}";
2842 		break;
2843 	case AMLOP_MATCH:
2844 		ch = "%m(%n, %b, %n, %b, %n, %n)";
2845 		break;
2846 	case AMLOP_LOADTABLE:
2847 		ch = "%m(%n, %n, %n, %n, %n, %n)";
2848 		break;
2849 	default:
2850 		aml_die("opcode = %x\n", opcode);
2851 		break;
2852 	}
2853 
2854 	/* Parse printable buffer args */
2855 	while (ch && *ch) {
2856 		char c;
2857 
2858 		if (*ch != '%') {
2859 			dbprintf(arg,"%c", *(ch++));
2860 			continue;
2861 		}
2862 		c = *(++ch);
2863 		switch (c) {
2864 		case 'b':
2865 		case 'w':
2866 		case 'd':
2867 		case 'q':
2868 			/* Parse simple object: don't allocate */
2869 			aml_parsesimple(scope, c, &tmp);
2870 			dbprintf(arg,"0x%llx", tmp.v_integer);
2871 			break;
2872 		case 'a':
2873 			dbprintf(arg, "\'%s\'", scope->pos);
2874 			scope->pos += strlen(scope->pos)+1;
2875 			break;
2876 		case 'N':
2877 			/* Create Name */
2878 			rv = aml_parsesimple(scope, c, NULL);
2879 			dbprintf(arg,aml_nodename(rv->node));
2880 			break;
2881 		case 'm':
2882 			/* display mnemonic */
2883 			dbprintf(arg,htab->mnem);
2884 			break;
2885 		case 'R':
2886 			/* Search name */
2887 			printf("%s", aml_getname(scope->pos));
2888 			scope->pos = aml_parsename(scope->node, scope->pos,
2889 			    &rv, 0);
2890 			aml_delref(&rv, 0);
2891 			break;
2892 		case 'z':
2893 		case 'n':
2894 			/* generic arg: recurse */
2895 			aml_disasm(scope, lvl | 0x8000, dbprintf, arg);
2896 			break;
2897 		case 'B':
2898 			/* Buffer */
2899 			scope->pos = end;
2900 			break;
2901 		case 'F':
2902 			/* Scope: Field List */
2903 			memset(&ms, 0, sizeof(ms));
2904 			ms.node = scope->node;
2905 			ms.start = scope->pos;
2906 			ms.end = end;
2907 			ms.pos = ms.start;
2908 			ms.type = AMLOP_FIELD;
2909 
2910 			while (ms.pos < ms.end) {
2911 				if (*ms.pos == 0x00) {
2912 					ms.pos++;
2913 					aml_parselength(&ms);
2914 				} else if (*ms.pos == 0x01) {
2915 					ms.pos+=3;
2916 				} else {
2917 					ms.pos = aml_parsename(ms.node,
2918 					     ms.pos, &rv, 1);
2919 					aml_parselength(&ms);
2920 					dbprintf(arg,"	%s\n",
2921 					    aml_nodename(rv->node));
2922 					aml_delref(&rv, 0);
2923 				}
2924 			}
2925 
2926 			/* Display address and closing bracket */
2927 			dbprintf(arg,"%.4x ", aml_pc(scope->pos));
2928 			for (pc=0; pc<(lvl & 0x7FFF); pc++) {
2929 				dbprintf(arg,"  ");
2930 			}
2931 			scope->pos = end;
2932 			break;
2933 		case 'T':
2934 			/* Scope: Termlist */
2935 			memset(&ms, 0, sizeof(ms));
2936 			ms.node = scope->node;
2937 			ms.start = scope->pos;
2938 			ms.end = end;
2939 			ms.pos = ms.start;
2940 			ms.type = AMLOP_SCOPE;
2941 
2942 			while (ms.pos < ms.end) {
2943 				aml_disasm(&ms, (lvl + 1) & 0x7FFF,
2944 				    dbprintf, arg);
2945 			}
2946 
2947 			/* Display address and closing bracket */
2948 			dbprintf(arg,"%.4x ", aml_pc(scope->pos));
2949 			for (pc=0; pc<(lvl & 0x7FFF); pc++) {
2950 				dbprintf(arg,"  ");
2951 			}
2952 			scope->pos = end;
2953 			break;
2954 		}
2955 		ch++;
2956 	}
2957 	if (lvl <= 0x7FFF) {
2958 		dbprintf(arg,"\n");
2959 	}
2960 }
2961 #endif /* DDB */
2962 
2963 int aml_busy;
2964 
2965 /* Evaluate method or buffervalue objects */
2966 struct aml_value *
2967 aml_eval(struct aml_scope *scope, struct aml_value *my_ret, int ret_type,
2968     int argc, struct aml_value *argv)
2969 {
2970 	struct aml_value *tmp = my_ret;
2971 	struct aml_scope *ms;
2972 	int idx;
2973 
2974 	switch (tmp->type) {
2975 	case AML_OBJTYPE_NAMEREF:
2976 		my_ret = aml_seterror(scope, "Undefined name: %s",
2977 		    aml_getname(my_ret->v_nameref));
2978 		break;
2979 	case AML_OBJTYPE_METHOD:
2980 		dnprintf(10,"\n--== Eval Method [%s, %d args] to %c ==--\n",
2981 		    aml_nodename(tmp->node),
2982 		    AML_METHOD_ARGCOUNT(tmp->v_method.flags),
2983 		    ret_type);
2984 		ms = aml_pushscope(scope, tmp, tmp->node, AMLOP_METHOD);
2985 
2986 		/* Parse method arguments */
2987 		for (idx=0; idx<AML_METHOD_ARGCOUNT(tmp->v_method.flags); idx++) {
2988 			struct aml_value *sp;
2989 
2990 			sp = aml_getstack(ms, AMLOP_ARG0+idx);
2991 			if (argv) {
2992 				aml_copyvalue(sp, &argv[idx]);
2993 			} else {
2994 				_aml_setvalue(sp, AML_OBJTYPE_OBJREF, AMLOP_ARG0 + idx, 0);
2995 				sp->v_objref.ref = aml_parse(scope, 't', "ARGX");
2996 			}
2997 		}
2998 #ifdef ACPI_DEBUG
2999 		aml_showstack(ms);
3000 #endif
3001 
3002 		/* Evaluate method scope */
3003 		aml_root.start = tmp->v_method.base;
3004 		if (tmp->v_method.fneval != NULL) {
3005 			my_ret = tmp->v_method.fneval(ms, NULL);
3006 		} else {
3007 			aml_parse(ms, 'T', "METHEVAL");
3008 			my_ret = ms->retv;
3009 		}
3010 		dnprintf(10,"\n--==Finished evaluating method: %s %c\n",
3011 		    aml_nodename(tmp->node), ret_type);
3012 #ifdef ACPI_DEBUG
3013 		aml_showvalue(my_ret, 0);
3014 		aml_showstack(ms);
3015 #endif
3016 		aml_popscope(ms);
3017 		break;
3018 	case AML_OBJTYPE_BUFFERFIELD:
3019 	case AML_OBJTYPE_FIELDUNIT:
3020 		my_ret = aml_allocvalue(0,0,NULL);
3021 		dnprintf(20,"quick: Convert Bufferfield to %c 0x%x\n",
3022 		    ret_type, my_ret);
3023 		aml_rwfield(tmp, 0, tmp->v_field.bitlen, my_ret, ACPI_IOREAD);
3024 		break;
3025 	}
3026 	if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
3027 #ifndef SMALL_KERNEL
3028 		aml_showvalue(my_ret, 8-100);
3029 #endif
3030 		aml_die("Not Integer");
3031 	}
3032 	return my_ret;
3033 }
3034 
3035 /*
3036  * The following opcodes produce return values
3037  *   TOSTRING	-> Str
3038  *   TOHEXSTR	-> Str
3039  *   TODECSTR	-> Str
3040  *   STRINGPFX	-> Str
3041  *   BUFFER	-> Buf
3042  *   CONCATRES	-> Buf
3043  *   TOBUFFER	-> Buf
3044  *   MID	-> Buf|Str
3045  *   CONCAT	-> Buf|Str
3046  *   PACKAGE	-> Pkg
3047  *   VARPACKAGE -> Pkg
3048  *   LOCALx	-> Obj
3049  *   ARGx	-> Obj
3050  *   NAMECHAR	-> Obj
3051  *   REFOF	-> ObjRef
3052  *   INDEX	-> ObjRef
3053  *   DEREFOF	-> DataRefObj
3054  *   COPYOBJECT -> DataRefObj
3055  *   STORE	-> DataRefObj
3056 
3057  *   ZERO	-> Int
3058  *   ONE	-> Int
3059  *   ONES	-> Int
3060  *   REVISION	-> Int
3061  *   B/W/D/Q	-> Int
3062  *   OR		-> Int
3063  *   AND	-> Int
3064  *   ADD	-> Int
3065  *   NAND	-> Int
3066  *   XOR	-> Int
3067  *   SHL	-> Int
3068  *   SHR	-> Int
3069  *   NOR	-> Int
3070  *   MOD	-> Int
3071  *   SUBTRACT	-> Int
3072  *   MULTIPLY	-> Int
3073  *   DIVIDE	-> Int
3074  *   NOT	-> Int
3075  *   TOBCD	-> Int
3076  *   FROMBCD	-> Int
3077  *   FSLEFTBIT	-> Int
3078  *   FSRIGHTBIT -> Int
3079  *   INCREMENT	-> Int
3080  *   DECREMENT	-> Int
3081  *   TOINTEGER	-> Int
3082  *   MATCH	-> Int
3083  *   SIZEOF	-> Int
3084  *   OBJECTTYPE -> Int
3085  *   TIMER	-> Int
3086 
3087  *   CONDREFOF	-> Bool
3088  *   ACQUIRE	-> Bool
3089  *   WAIT	-> Bool
3090  *   LNOT	-> Bool
3091  *   LAND	-> Bool
3092  *   LOR	-> Bool
3093  *   LLESS	-> Bool
3094  *   LEQUAL	-> Bool
3095  *   LGREATER	-> Bool
3096  *   LNOTEQUAL	-> Bool
3097  *   LLESSEQUAL -> Bool
3098  *   LGREATEREQ -> Bool
3099 
3100  *   LOADTABLE	-> DDB
3101  *   DEBUG	-> Debug
3102 
3103  *   The following opcodes do not generate a return value:
3104  *   NOP
3105  *   BREAKPOINT
3106  *   RELEASE
3107  *   RESET
3108  *   SIGNAL
3109  *   NAME
3110  *   ALIAS
3111  *   OPREGION
3112  *   DATAREGION
3113  *   EVENT
3114  *   MUTEX
3115  *   SCOPE
3116  *   DEVICE
3117  *   THERMALZONE
3118  *   POWERRSRC
3119  *   PROCESSOR
3120  *   METHOD
3121  *   CREATEFIELD
3122  *   CREATEBITFIELD
3123  *   CREATEBYTEFIELD
3124  *   CREATEWORDFIELD
3125  *   CREATEDWORDFIELD
3126  *   CREATEQWORDFIELD
3127  *   FIELD
3128  *   INDEXFIELD
3129  *   BANKFIELD
3130  *   STALL
3131  *   SLEEP
3132  *   NOTIFY
3133  *   FATAL
3134  *   LOAD
3135  *   UNLOAD
3136  *   IF
3137  *   ELSE
3138  *   WHILE
3139  *   BREAK
3140  *   CONTINUE
3141  */
3142 
3143 /* Parse a simple object from AML Bytestream */
3144 struct aml_value *
3145 aml_parsesimple(struct aml_scope *scope, char ch, struct aml_value *rv)
3146 {
3147 	if (rv == NULL)
3148 		rv = aml_allocvalue(0,0,NULL);
3149 	switch (ch) {
3150 	case AML_ARG_REVISION:
3151 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER, AML_REVISION, NULL);
3152 		break;
3153 	case AML_ARG_DEBUG:
3154 		_aml_setvalue(rv, AML_OBJTYPE_DEBUGOBJ, 0, NULL);
3155 		break;
3156 	case AML_ARG_BYTE:
3157 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3158 		    aml_get8(scope->pos), NULL);
3159 		scope->pos += 1;
3160 		break;
3161 	case AML_ARG_WORD:
3162 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3163 		    aml_get16(scope->pos), NULL);
3164 		scope->pos += 2;
3165 		break;
3166 	case AML_ARG_DWORD:
3167 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3168 		    aml_get32(scope->pos), NULL);
3169 		scope->pos += 4;
3170 		break;
3171 	case AML_ARG_QWORD:
3172 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3173 		    aml_get64(scope->pos), NULL);
3174 		scope->pos += 8;
3175 		break;
3176 	case AML_ARG_STRING:
3177 		_aml_setvalue(rv, AML_OBJTYPE_STRING, -1, scope->pos);
3178 		scope->pos += rv->length+1;
3179 		break;
3180 	}
3181 	return rv;
3182 }
3183 
3184 /*
3185  * Main Opcode Parser/Evaluator
3186  *
3187  * ret_type is expected type for return value
3188  *   'o' = Data Object (Int/Str/Buf/Pkg/Name)
3189  *   'i' = Integer
3190  *   't' = TermArg     (Int/Str/Buf/Pkg)
3191  *   'r' = Target      (NamedObj/Local/Arg/Null)
3192  *   'S' = SuperName   (NamedObj/Local/Arg)
3193  *   'T' = TermList
3194  */
3195 #define aml_debugger(x)
3196 
3197 int maxdp;
3198 
3199 struct aml_value *
3200 aml_gettgt(struct aml_value *val, int opcode)
3201 {
3202 	while (val && val->type == AML_OBJTYPE_OBJREF) {
3203 		val = val->v_objref.ref;
3204 	}
3205 	return val;
3206 }
3207 
3208 struct aml_value *
3209 aml_seterror(struct aml_scope *scope, const char *fmt, ...)
3210 {
3211 	va_list ap;
3212 
3213 	va_start(ap, fmt);
3214 	printf("### AML PARSE ERROR (0x%x): ", aml_pc(scope->pos));
3215 	vprintf(fmt, ap);
3216 	printf("\n");
3217 	va_end(ap);
3218 
3219 	while (scope) {
3220 		scope->pos = scope->end;
3221 		scope = scope->parent;
3222 	}
3223 	aml_error++;
3224 	return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
3225 }
3226 
3227 /* Load new SSDT scope from memory address */
3228 struct aml_scope *
3229 aml_load(struct acpi_softc *sc, struct aml_scope *scope,
3230     struct aml_value *rgn, struct aml_value *ddb)
3231 {
3232 	struct acpi_q *entry;
3233 	struct acpi_dsdt *p_ssdt;
3234 	struct aml_value tmp;
3235 
3236 	ddb->type = AML_OBJTYPE_DDBHANDLE;
3237 	ddb->v_integer = 0;
3238 
3239 	memset(&tmp, 0, sizeof(tmp));
3240 	if (rgn->type != AML_OBJTYPE_OPREGION ||
3241 	    rgn->v_opregion.iospace != GAS_SYSTEM_MEMORY)
3242 		goto fail;
3243 
3244 	/* Load SSDT from memory */
3245 	entry = acpi_maptable(sc, rgn->v_opregion.iobase, "SSDT", NULL, NULL, 1);
3246 	if (entry == NULL)
3247 		goto fail;
3248 
3249 	dnprintf(10, "%s: loaded SSDT %s @ %llx\n", sc->sc_dev.dv_xname,
3250 	    aml_nodename(rgn->node), rgn->v_opregion.iobase);
3251 	ddb->v_integer = entry->q_id;
3252 
3253 	p_ssdt = entry->q_table;
3254 	tmp.v_buffer = p_ssdt->aml;
3255 	tmp.length   = p_ssdt->hdr_length - sizeof(p_ssdt->hdr);
3256 
3257 	return aml_pushscope(scope, &tmp, scope->node,
3258 	    AMLOP_LOAD);
3259 fail:
3260 	printf("%s: unable to load %s\n", sc->sc_dev.dv_xname,
3261 	    aml_nodename(rgn->node));
3262 	return NULL;
3263 }
3264 
3265 struct aml_value *
3266 aml_parse(struct aml_scope *scope, int ret_type, const char *stype)
3267 {
3268 	int    opcode, idx, pc;
3269 	struct aml_opcode *htab;
3270 	struct aml_value *opargs[8], *my_ret, *rv;
3271 	struct aml_scope *mscope, *iscope;
3272 	uint8_t *start, *end;
3273 	const char *ch;
3274 	int64_t ival;
3275 
3276 	my_ret = NULL;
3277 	if (scope == NULL || scope->pos >= scope->end) {
3278 		return NULL;
3279 	}
3280 	if (odp++ > 125)
3281 		panic("depth");
3282 	if (odp > maxdp) {
3283 		maxdp = odp;
3284 		dnprintf(10, "max depth: %d\n", maxdp);
3285 	}
3286 	end = NULL;
3287 	iscope = scope;
3288  start:
3289 	/* --== Stage 0: Get Opcode ==-- */
3290 	start = scope->pos;
3291 	pc = aml_pc(scope->pos);
3292 	aml_debugger(scope);
3293 
3294 	opcode = aml_parseopcode(scope);
3295 	htab = aml_findopcode(opcode);
3296 	if (htab == NULL) {
3297 		/* No opcode handler */
3298 		aml_die("Unknown opcode: %.4x @ %.4x", opcode, pc);
3299 	}
3300 	dnprintf(18,"%.4x %s\n", pc, aml_mnem(opcode, scope->pos));
3301 
3302 	/* --== Stage 1: Process opcode arguments ==-- */
3303 	memset(opargs, 0, sizeof(opargs));
3304 	idx = 0;
3305 	for (ch = htab->args; *ch; ch++) {
3306 		rv = NULL;
3307 		switch (*ch) {
3308 		case AML_ARG_OBJLEN:
3309 			end = aml_parseend(scope);
3310 			break;
3311 		case AML_ARG_IFELSE:
3312                         /* Special Case: IF-ELSE:piTbpT or IF:piT */
3313 			ch = (*end == AMLOP_ELSE && end < scope->end) ?
3314 			    "-TbpT" : "-T";
3315 			break;
3316 
3317 			/* Complex arguments */
3318 		case 's':
3319 		case 'S':
3320 		case AML_ARG_TARGET:
3321 		case AML_ARG_TERMOBJ:
3322 		case AML_ARG_INTEGER:
3323 			if (*ch == 'r' && *scope->pos == AMLOP_ZERO) {
3324 				/* Special case: NULL Target */
3325 				rv = aml_allocvalue(AML_OBJTYPE_NOTARGET, 0, NULL);
3326 				scope->pos++;
3327 			}
3328 			else {
3329 				rv = aml_parse(scope, *ch, htab->mnem);
3330 				if (rv == NULL || aml_error)
3331 					goto parse_error;
3332 			}
3333 			break;
3334 
3335 			/* Simple arguments */
3336 		case AML_ARG_BUFFER:
3337 		case AML_ARG_METHOD:
3338 		case AML_ARG_FIELDLIST:
3339 		case AML_ARG_TERMOBJLIST:
3340 			rv = aml_allocvalue(AML_OBJTYPE_SCOPE, 0, NULL);
3341 			rv->v_buffer = scope->pos;
3342 			rv->length = end - scope->pos;
3343 			scope->pos = end;
3344 			break;
3345 		case AML_ARG_CONST:
3346 			rv = aml_allocvalue(AML_OBJTYPE_INTEGER,
3347 			    (char)opcode, NULL);
3348 			break;
3349 		case AML_ARG_CREATENAME:
3350 			scope->pos = aml_parsename(scope->node, scope->pos,
3351 			    &rv, 1);
3352 			break;
3353 		case AML_ARG_SEARCHNAME:
3354 			scope->pos = aml_parsename(scope->node, scope->pos,
3355 			    &rv, 0);
3356 			break;
3357 		case AML_ARG_BYTE:
3358 		case AML_ARG_WORD:
3359 		case AML_ARG_DWORD:
3360 		case AML_ARG_QWORD:
3361 		case AML_ARG_DEBUG:
3362 		case AML_ARG_STRING:
3363 		case AML_ARG_REVISION:
3364 			rv = aml_parsesimple(scope, *ch, NULL);
3365 			break;
3366 		case AML_ARG_STKLOCAL:
3367 		case AML_ARG_STKARG:
3368 			rv = aml_getstack(scope, opcode);
3369 			break;
3370 		default:
3371 			aml_die("Unknown arg type: %c\n", *ch);
3372 			break;
3373 		}
3374 		if (rv != NULL)
3375 			opargs[idx++] = rv;
3376 		}
3377 
3378 	/* --== Stage 2: Process opcode ==-- */
3379 	ival = 0;
3380 	my_ret = NULL;
3381 	mscope = NULL;
3382 	switch (opcode) {
3383 	case AMLOP_NOP:
3384 	case AMLOP_BREAKPOINT:
3385 		break;
3386 	case AMLOP_LOCAL0:
3387 	case AMLOP_LOCAL1:
3388 	case AMLOP_LOCAL2:
3389 	case AMLOP_LOCAL3:
3390 	case AMLOP_LOCAL4:
3391 	case AMLOP_LOCAL5:
3392 	case AMLOP_LOCAL6:
3393 	case AMLOP_LOCAL7:
3394 	case AMLOP_ARG0:
3395 	case AMLOP_ARG1:
3396 	case AMLOP_ARG2:
3397 	case AMLOP_ARG3:
3398 	case AMLOP_ARG4:
3399 	case AMLOP_ARG5:
3400 	case AMLOP_ARG6:
3401 		my_ret = opargs[0];
3402 		aml_addref(my_ret, htab->mnem);
3403 		break;
3404 	case AMLOP_NAMECHAR:
3405 		/* opargs[0] = named object (node != NULL), or nameref */
3406 		my_ret = opargs[0];
3407 		if (scope->type == AMLOP_PACKAGE) {
3408 			/* Special case for package */
3409 			if (my_ret->type == AML_OBJTYPE_NAMEREF)
3410 				my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
3411 				    aml_getname(my_ret->v_nameref));
3412 			else if (my_ret->node)
3413 				my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
3414 				    aml_nodename(my_ret->node));
3415 			break;
3416 		}
3417 		if (my_ret->type == AML_OBJTYPE_OBJREF) {
3418 			my_ret = my_ret->v_objref.ref;
3419 			aml_addref(my_ret, "de-alias");
3420 		}
3421 		if (ret_type == 'i' || ret_type == 't' || ret_type == 'T') {
3422 			/* Return TermArg or Integer: Evaluate object */
3423 			my_ret = aml_eval(scope, my_ret, ret_type, 0, NULL);
3424 		} else if (my_ret->type == AML_OBJTYPE_METHOD) {
3425 			/* This should only happen with CondRef */
3426 			dnprintf(12,"non-termarg method : %s\n", stype);
3427 			aml_addref(my_ret, "zoom");
3428 		}
3429 		break;
3430 
3431 	case AMLOP_ZERO:
3432 	case AMLOP_ONE:
3433 	case AMLOP_ONES:
3434 	case AMLOP_DEBUG:
3435 	case AMLOP_REVISION:
3436 	case AMLOP_BYTEPREFIX:
3437 	case AMLOP_WORDPREFIX:
3438 	case AMLOP_DWORDPREFIX:
3439 	case AMLOP_QWORDPREFIX:
3440 	case AMLOP_STRINGPREFIX:
3441 		my_ret = opargs[0];
3442 		break;
3443 
3444 	case AMLOP_BUFFER:
3445 		/* Buffer: iB => Buffer */
3446 		my_ret = aml_allocvalue(AML_OBJTYPE_BUFFER,
3447 		    opargs[0]->v_integer, NULL);
3448 		memcpy(my_ret->v_buffer, opargs[1]->v_buffer,
3449 		    opargs[1]->length);
3450 		break;
3451 	case AMLOP_PACKAGE:
3452 	case AMLOP_VARPACKAGE:
3453 		/* Package/VarPackage: bT/iT => Package */
3454 		my_ret = aml_allocvalue(AML_OBJTYPE_PACKAGE,
3455 		    opargs[0]->v_integer, 0);
3456 		mscope = aml_pushscope(scope, opargs[1], scope->node,
3457 		    AMLOP_PACKAGE);
3458 
3459 		/* Recursively parse package contents */
3460 		for (idx=0; idx<my_ret->length; idx++) {
3461 			rv = aml_parse(mscope, 'o', "Package");
3462 			if (rv != NULL) {
3463 				aml_delref(&my_ret->v_package[idx], "pkginit");
3464 				my_ret->v_package[idx] = rv;
3465 			}
3466 		}
3467 		aml_popscope(mscope);
3468 		mscope = NULL;
3469 		break;
3470 
3471 		/* Math/Logical operations */
3472 	case AMLOP_OR:
3473 	case AMLOP_ADD:
3474 	case AMLOP_AND:
3475 	case AMLOP_NAND:
3476 	case AMLOP_XOR:
3477 	case AMLOP_SHL:
3478 	case AMLOP_SHR:
3479 	case AMLOP_NOR:
3480 	case AMLOP_MOD:
3481 	case AMLOP_SUBTRACT:
3482 	case AMLOP_MULTIPLY:
3483 		/* XXX: iir => I */
3484 		ival = aml_evalexpr(opargs[0]->v_integer,
3485 		    opargs[1]->v_integer, opcode);
3486 		aml_store(scope, opargs[2], ival, NULL);
3487 		break;
3488 	case AMLOP_DIVIDE:
3489 		/* Divide: iirr => I */
3490 		if (opargs[1]->v_integer == 0) {
3491 			my_ret = aml_seterror(scope, "Divide by Zero!");
3492 			break;
3493 		}
3494 		ival = aml_evalexpr(opargs[0]->v_integer,
3495 		    opargs[1]->v_integer, AMLOP_MOD);
3496 		aml_store(scope, opargs[2], ival, NULL);
3497 
3498 		ival = aml_evalexpr(opargs[0]->v_integer,
3499 		    opargs[1]->v_integer, AMLOP_DIVIDE);
3500 		aml_store(scope, opargs[3], ival, NULL);
3501 		break;
3502 	case AMLOP_NOT:
3503 	case AMLOP_TOBCD:
3504 	case AMLOP_FROMBCD:
3505 	case AMLOP_FINDSETLEFTBIT:
3506 	case AMLOP_FINDSETRIGHTBIT:
3507 		/* XXX: ir => I */
3508 		ival = aml_evalexpr(opargs[0]->v_integer, 0, opcode);
3509 		aml_store(scope, opargs[1], ival, NULL);
3510 		break;
3511 	case AMLOP_INCREMENT:
3512 	case AMLOP_DECREMENT:
3513 		/* Inc/Dec: S => I */
3514 		my_ret = aml_eval(scope, opargs[0], AML_ARG_INTEGER, 0, NULL);
3515 		ival = aml_evalexpr(my_ret->v_integer, 1, opcode);
3516 		aml_store(scope, opargs[0], ival, NULL);
3517 		break;
3518 	case AMLOP_LNOT:
3519 		/* LNot: i => Bool */
3520 		ival = aml_evalexpr(opargs[0]->v_integer, 0, opcode);
3521 		break;
3522 	case AMLOP_LOR:
3523 	case AMLOP_LAND:
3524 		/* XXX: ii => Bool */
3525 		ival = aml_evalexpr(opargs[0]->v_integer,
3526 		    opargs[1]->v_integer, opcode);
3527 		break;
3528 	case AMLOP_LLESS:
3529 	case AMLOP_LEQUAL:
3530 	case AMLOP_LGREATER:
3531 	case AMLOP_LNOTEQUAL:
3532 	case AMLOP_LLESSEQUAL:
3533 	case AMLOP_LGREATEREQUAL:
3534 		/* XXX: tt => Bool */
3535 		ival = aml_compare(opargs[0], opargs[1], opcode);
3536 		break;
3537 
3538 		/* Reference/Store operations */
3539 	case AMLOP_CONDREFOF:
3540 		/* CondRef: rr => I */
3541 		ival = 0;
3542 		if (opargs[0]->node != NULL) {
3543 			/* Create Object Reference */
3544 			rv = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode,
3545 				opargs[0]);
3546 			aml_addref(opargs[0], "CondRef");
3547 			aml_store(scope, opargs[1], 0, rv);
3548 			aml_delref(&rv, 0);
3549 
3550 			/* Mark that we found it */
3551 			ival = -1;
3552 		}
3553 		break;
3554 	case AMLOP_REFOF:
3555 		/* RefOf: r => ObjRef */
3556 		my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode, opargs[0]);
3557 		aml_addref(my_ret->v_objref.ref, "RefOf");
3558 		break;
3559 	case AMLOP_INDEX:
3560 		/* Index: tir => ObjRef */
3561 		idx = opargs[1]->v_integer;
3562 		if (idx >= opargs[0]->length || idx < 0) {
3563 #ifndef SMALL_KERNEL
3564 			aml_showvalue(opargs[0], 0);
3565 #endif
3566 			aml_die("Index out of bounds %d/%d\n", idx,
3567 			    opargs[0]->length);
3568 		}
3569 		switch (opargs[0]->type) {
3570 		case AML_OBJTYPE_PACKAGE:
3571 			/* Don't set opargs[0] to NULL */
3572 			if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
3573 				my_ret = opargs[0]->v_package[idx];
3574 				aml_addref(my_ret, "Index.Package");
3575 			} else {
3576 				my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, AMLOP_PACKAGE,
3577 				    opargs[0]->v_package[idx]);
3578 				aml_addref(my_ret->v_objref.ref,
3579 				    "Index.Package");
3580 			}
3581 			break;
3582 		case AML_OBJTYPE_BUFFER:
3583 		case AML_OBJTYPE_STRING:
3584 		case AML_OBJTYPE_INTEGER:
3585 			rv = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
3586 			if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
3587 				dnprintf(12,"Index.Buf Term: %d = %x\n",
3588 				    idx, rv->v_buffer[idx]);
3589 				ival = rv->v_buffer[idx];
3590 			} else {
3591 				dnprintf(12, "Index.Buf Targ\n");
3592 				my_ret = aml_allocvalue(0,0,NULL);
3593 				aml_createfield(my_ret, AMLOP_INDEX, rv,
3594 				    8 * idx, 8, NULL, 0, AML_FIELD_BYTEACC);
3595 			}
3596 			aml_delref(&rv, "Index.BufStr");
3597 			break;
3598 		default:
3599 			aml_die("Unknown index : %x\n", opargs[0]->type);
3600 			break;
3601 		}
3602 		aml_store(scope, opargs[2], ival, my_ret);
3603 		break;
3604 	case AMLOP_DEREFOF:
3605 		/* DerefOf: t:ObjRef => DataRefObj */
3606 		if (opargs[0]->type == AML_OBJTYPE_OBJREF) {
3607 			my_ret = opargs[0]->v_objref.ref;
3608 			aml_addref(my_ret, "DerefOf");
3609 		} else {
3610 			my_ret = opargs[0];
3611 			//aml_addref(my_ret, "DerefOf");
3612 		}
3613 		break;
3614 	case AMLOP_COPYOBJECT:
3615 		/* CopyObject: t:DataRefObj, s:implename => DataRefObj */
3616 		my_ret = opargs[0];
3617 		aml_freevalue(opargs[1]);
3618 		aml_copyvalue(opargs[1], opargs[0]);
3619 		break;
3620 	case AMLOP_STORE:
3621 		/* Store: t:DataRefObj, S:upername => DataRefObj */
3622 		my_ret = opargs[0];
3623 		aml_store(scope, opargs[1], 0, opargs[0]);
3624 		break;
3625 
3626 		/* Conversion */
3627 	case AMLOP_TOINTEGER:
3628 		/* Source:CData, Result => Integer */
3629 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_INTEGER, -1);
3630 		aml_store(scope, opargs[1], 0, my_ret);
3631 		break;
3632 	case AMLOP_TOBUFFER:
3633 		/* Source:CData, Result => Buffer */
3634 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
3635 		aml_store(scope, opargs[1], 0, my_ret);
3636 		break;
3637 	case AMLOP_TOHEXSTRING:
3638 		/* Source:CData, Result => String */
3639 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_HEXSTRING, -1);
3640 		aml_store(scope, opargs[1], 0, my_ret);
3641 		break;
3642 	case AMLOP_TODECSTRING:
3643 		/* Source:CData, Result => String */
3644 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_DECSTRING, -1);
3645 		aml_store(scope, opargs[1], 0, my_ret);
3646 		break;
3647 	case AMLOP_TOSTRING:
3648 		/* Source:B, Length:I, Result => String */
3649 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_STRING,
3650 		    opargs[1]->v_integer);
3651 		aml_store(scope, opargs[2], 0, my_ret);
3652 		break;
3653 	case AMLOP_CONCAT:
3654 		/* Source1:CData, Source2:CData, Result => CData */
3655 		my_ret = aml_concat(opargs[0], opargs[1]);
3656 		aml_store(scope, opargs[2], 0, my_ret);
3657 		break;
3658 	case AMLOP_CONCATRES:
3659 		/* Concat two resource buffers: buf1, buf2, result => Buffer */
3660 		my_ret = aml_concatres(opargs[0], opargs[1]);
3661 		aml_store(scope, opargs[2], 0, my_ret);
3662 		break;
3663 	case AMLOP_MID:
3664 		/* Source:BS, Index:I, Length:I, Result => BS */
3665 		my_ret = aml_mid(opargs[0], opargs[1]->v_integer,
3666 		    opargs[2]->v_integer);
3667 		aml_store(scope, opargs[3], 0, my_ret);
3668 		break;
3669 	case AMLOP_MATCH:
3670 		/* Match: Pkg, Op1, Val1, Op2, Val2, Index */
3671 		ival = aml_match(opargs[0], opargs[5]->v_integer,
3672 		    opargs[1]->v_integer, opargs[2]->v_integer,
3673 		    opargs[3]->v_integer, opargs[4]->v_integer);
3674 		break;
3675 	case AMLOP_SIZEOF:
3676 		/* Sizeof: S => i */
3677 		rv = aml_gettgt(opargs[0], opcode);
3678 		ival = rv->length;
3679 		break;
3680 	case AMLOP_OBJECTTYPE:
3681 		/* ObjectType: S => i */
3682 		rv = aml_gettgt(opargs[0], opcode);
3683 		ival = rv->type;
3684 		break;
3685 
3686 		/* Mutex/Event handlers */
3687 	case AMLOP_ACQUIRE:
3688 		/* Acquire: Sw => Bool */
3689 		rv = aml_gettgt(opargs[0], opcode);
3690 		ival = acpi_mutex_acquire(scope, rv,
3691 		    opargs[1]->v_integer);
3692 		break;
3693 	case AMLOP_RELEASE:
3694 		/* Release: S */
3695 		rv = aml_gettgt(opargs[0], opcode);
3696 		acpi_mutex_release(scope, rv);
3697 		break;
3698 	case AMLOP_WAIT:
3699 		/* Wait: Si => Bool */
3700 		rv = aml_gettgt(opargs[0], opcode);
3701 		ival = acpi_event_wait(scope, rv,
3702 		    opargs[1]->v_integer);
3703 		break;
3704 	case AMLOP_RESET:
3705 		/* Reset: S */
3706 		rv = aml_gettgt(opargs[0], opcode);
3707 		acpi_event_reset(scope, rv);
3708 		break;
3709 	case AMLOP_SIGNAL:
3710 		/* Signal: S */
3711 		rv = aml_gettgt(opargs[0], opcode);
3712 		acpi_event_signal(scope, rv);
3713 		break;
3714 
3715 		/* Named objects */
3716 	case AMLOP_NAME:
3717 		/* Name: Nt */
3718 		rv = opargs[0];
3719 		aml_freevalue(rv);
3720 			aml_copyvalue(rv, opargs[1]);
3721 		break;
3722 	case AMLOP_ALIAS:
3723 		/* Alias: nN */
3724 		rv = _aml_setvalue(opargs[1], AML_OBJTYPE_OBJREF, opcode, 0);
3725 		rv->v_objref.ref = aml_gettgt(opargs[0], opcode);
3726 		aml_addref(rv->v_objref.ref, "Alias");
3727 		break;
3728 	case AMLOP_OPREGION:
3729 		/* OpRegion: Nbii */
3730 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
3731 		rv->v_opregion.iospace = opargs[1]->v_integer;
3732 		rv->v_opregion.iobase = opargs[2]->v_integer;
3733 		rv->v_opregion.iolen = opargs[3]->v_integer;
3734 		rv->v_opregion.flag = 0;
3735 		break;
3736 	case AMLOP_DATAREGION:
3737 		/* DataTableRegion: N,t:SigStr,t:OemIDStr,t:OemTableIDStr */
3738 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
3739 		rv->v_opregion.iospace = GAS_SYSTEM_MEMORY;
3740 		rv->v_opregion.iobase = 0;
3741 		rv->v_opregion.iolen = 0;
3742 		aml_die("AML-DataTableRegion\n");
3743 		break;
3744 	case AMLOP_EVENT:
3745 		/* Event: N */
3746 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_EVENT, 0, 0);
3747 		rv->v_integer = 0;
3748 		break;
3749 	case AMLOP_MUTEX:
3750 		/* Mutex: Nw */
3751 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_MUTEX, 0, 0);
3752 		rv->v_mtx.synclvl = opargs[1]->v_integer;
3753 		break;
3754 	case AMLOP_SCOPE:
3755 		/* Scope: NT */
3756 		rv = opargs[0];
3757 		if (rv->type == AML_OBJTYPE_NAMEREF) {
3758 			printf("Undefined scope: %s\n", aml_getname(rv->v_nameref));
3759 			break;
3760 		}
3761 		mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
3762 		break;
3763 	case AMLOP_DEVICE:
3764 		/* Device: NT */
3765 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_DEVICE, 0, 0);
3766 		mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
3767 		break;
3768 	case AMLOP_THERMALZONE:
3769 		/* ThermalZone: NT */
3770 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_THERMZONE, 0, 0);
3771 		mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
3772 		break;
3773 	case AMLOP_POWERRSRC:
3774 		/* PowerRsrc: NbwT */
3775 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_POWERRSRC, 0, 0);
3776 		rv->v_powerrsrc.pwr_level = opargs[1]->v_integer;
3777 		rv->v_powerrsrc.pwr_order = opargs[2]->v_integer;
3778 		mscope = aml_pushscope(scope, opargs[3], rv->node, opcode);
3779 		break;
3780 	case AMLOP_PROCESSOR:
3781 		/* Processor: NbdbT */
3782 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_PROCESSOR, 0, 0);
3783 		rv->v_processor.proc_id = opargs[1]->v_integer;
3784 		rv->v_processor.proc_addr = opargs[2]->v_integer;
3785 		rv->v_processor.proc_len = opargs[3]->v_integer;
3786 		mscope = aml_pushscope(scope, opargs[4], rv->node, opcode);
3787 		break;
3788 	case AMLOP_METHOD:
3789 		/* Method: NbM */
3790 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_METHOD, 0, 0);
3791 		rv->v_method.flags = opargs[1]->v_integer;
3792 		rv->v_method.start = opargs[2]->v_buffer;
3793 		rv->v_method.end = rv->v_method.start + opargs[2]->length;
3794 		rv->v_method.base = aml_root.start;
3795 		break;
3796 
3797 		/* Field objects */
3798 	case AMLOP_CREATEFIELD:
3799 		/* Source:B, BitIndex:I, NumBits:I, FieldName */
3800 		rv = _aml_setvalue(opargs[3], AML_OBJTYPE_BUFFERFIELD, 0, 0);
3801 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer,
3802 		    opargs[2]->v_integer, NULL, 0, 0);
3803 		break;
3804 	case AMLOP_CREATEBITFIELD:
3805 		/* Source:B, BitIndex:I, FieldName */
3806 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
3807 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer,
3808 		    1, NULL, 0, 0);
3809 		break;
3810 	case AMLOP_CREATEBYTEFIELD:
3811 		/* Source:B, ByteIndex:I, FieldName */
3812 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
3813 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
3814 		    8, NULL, 0, AML_FIELD_BYTEACC);
3815 		break;
3816 	case AMLOP_CREATEWORDFIELD:
3817 		/* Source:B, ByteIndex:I, FieldName */
3818 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
3819 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
3820 		    16, NULL, 0, AML_FIELD_WORDACC);
3821 		break;
3822 	case AMLOP_CREATEDWORDFIELD:
3823 		/* Source:B, ByteIndex:I, FieldName */
3824 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
3825 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
3826 		    32, NULL, 0, AML_FIELD_DWORDACC);
3827 		break;
3828 	case AMLOP_CREATEQWORDFIELD:
3829 		/* Source:B, ByteIndex:I, FieldName */
3830 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
3831 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
3832 		    64, NULL, 0, AML_FIELD_QWORDACC);
3833 		break;
3834 	case AMLOP_FIELD:
3835 		/* Field: n:OpRegion, b:Flags, F:ieldlist */
3836 		mscope = aml_pushscope(scope, opargs[2], scope->node, opcode);
3837 		aml_parsefieldlist(mscope, opcode, opargs[1]->v_integer,
3838 		    opargs[0], NULL, 0);
3839 		mscope = NULL;
3840 		break;
3841 	case AMLOP_INDEXFIELD:
3842 		/* IndexField: n:Index, n:Data, b:Flags, F:ieldlist */
3843 		mscope = aml_pushscope(scope, opargs[3], scope->node, opcode);
3844 		aml_parsefieldlist(mscope, opcode, opargs[2]->v_integer,
3845 		    opargs[1], opargs[0], 0);
3846 		mscope = NULL;
3847 		break;
3848 	case AMLOP_BANKFIELD:
3849 		/* BankField: n:OpRegion, n:Field, i:Bank, b:Flags, F:ieldlist */
3850 		mscope = aml_pushscope(scope, opargs[4], scope->node, opcode);
3851 		aml_parsefieldlist(mscope, opcode, opargs[3]->v_integer,
3852 		    opargs[0], opargs[1], opargs[2]->v_integer);
3853 		mscope = NULL;
3854 		break;
3855 
3856 		/* Misc functions */
3857 	case AMLOP_STALL:
3858 		/* Stall: i */
3859 		acpi_stall(opargs[0]->v_integer);
3860 		break;
3861 	case AMLOP_SLEEP:
3862 		/* Sleep: i */
3863 		acpi_sleep(opargs[0]->v_integer, "amlsleep");
3864 		break;
3865 	case AMLOP_NOTIFY:
3866 		/* Notify: Si */
3867 		rv = aml_gettgt(opargs[0], opcode);
3868 		dnprintf(50,"Notifying: %s %x\n",
3869 		    aml_nodename(rv->node),
3870 		    opargs[1]->v_integer);
3871 		aml_notify(rv->node, opargs[1]->v_integer);
3872 		break;
3873 	case AMLOP_TIMER:
3874 		/* Timer: => i */
3875 		ival = 0xDEADBEEF;
3876 		break;
3877 	case AMLOP_FATAL:
3878 		/* Fatal: bdi */
3879 		aml_die("AML FATAL ERROR: %x,%x,%x\n",
3880 		    opargs[0]->v_integer, opargs[1]->v_integer,
3881 		    opargs[2]->v_integer);
3882 		break;
3883 	case AMLOP_LOADTABLE:
3884 		/* LoadTable(Sig:Str, OEMID:Str, OEMTable:Str, [RootPath:Str], [ParmPath:Str],
3885 		   [ParmData:DataRefObj]) => DDBHandle */
3886 		aml_die("LoadTable");
3887 		break;
3888 	case AMLOP_LOAD:
3889 		/* Load(Object:NameString, DDBHandle:SuperName) */
3890 		mscope = aml_load(acpi_softc, scope, opargs[0], opargs[1]);
3891 		break;
3892 	case AMLOP_UNLOAD:
3893 		/* DDBHandle */
3894 		aml_die("Unload");
3895 		break;
3896 
3897 		/* Control Flow */
3898 	case AMLOP_IF:
3899 		/* Arguments: iT or iTbT */
3900 		if (opargs[0]->v_integer) {
3901 			dnprintf(10,"parse-if @ %.4x\n", pc);
3902 			mscope = aml_pushscope(scope, opargs[1], scope->node,
3903 			    AMLOP_IF);
3904 		} else if (opargs[3] != NULL) {
3905 			dnprintf(10,"parse-else @ %.4x\n", pc);
3906 			mscope = aml_pushscope(scope, opargs[3], scope->node,
3907 			    AMLOP_ELSE);
3908 		}
3909 		break;
3910 	case AMLOP_WHILE:
3911 		if (opargs[0]->v_integer) {
3912 			/* Set parent position to start of WHILE */
3913 			scope->pos = start;
3914 			mscope = aml_pushscope(scope, opargs[1], scope->node,
3915 			    AMLOP_WHILE);
3916 		}
3917 		break;
3918 	case AMLOP_BREAK:
3919 		/* Break: Find While Scope parent, mark type as null */
3920 		aml_findscope(scope, AMLOP_WHILE, AMLOP_BREAK);
3921 		break;
3922 	case AMLOP_CONTINUE:
3923 		/* Find Scope.. mark all objects as invalid on way to root */
3924 		aml_findscope(scope, AMLOP_WHILE, AMLOP_CONTINUE);
3925 		break;
3926 	case AMLOP_RETURN:
3927 		mscope = aml_findscope(scope, AMLOP_METHOD, AMLOP_RETURN);
3928 		if (mscope->retv) {
3929 			aml_die("already allocated\n");
3930 		}
3931 		mscope->retv = aml_allocvalue(0,0,NULL);
3932 		aml_copyvalue(mscope->retv, opargs[0]);
3933 		mscope = NULL;
3934 		break;
3935 	default:
3936 		/* may be set direct result */
3937 		aml_die("Unknown opcode: %x:%s\n", opcode, htab->mnem);
3938 		break;
3939 	}
3940 	if (mscope != NULL) {
3941 		/* Change our scope to new scope */
3942 		scope = mscope;
3943 	}
3944 	if ((ret_type == 'i' || ret_type == 't') && my_ret == NULL) {
3945 		dnprintf(10,"quick: %.4x [%s] alloc return integer = 0x%llx\n",
3946 		    pc, htab->mnem, ival);
3947 		my_ret = aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL);
3948 	}
3949 	if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
3950 		dnprintf(10,"quick: %.4x convert to integer %s -> %s\n",
3951 		    pc, htab->mnem, stype);
3952 		my_ret = aml_convert(my_ret, AML_OBJTYPE_INTEGER, -1);
3953 	}
3954 	if (my_ret != NULL) {
3955 		/* Display result */
3956 		dnprintf(20,"quick: %.4x %18s %c %.4x\n", pc, stype,
3957 		    ret_type, my_ret->stack);
3958 	}
3959 
3960 	/* End opcode: display/free arguments */
3961 parse_error:
3962 	for (idx=0; idx<8; idx++) {
3963 		if (opargs[idx] == my_ret)
3964 			opargs[idx] = NULL;
3965 		aml_delref(&opargs[idx], "oparg");
3966 	}
3967 
3968 	/* If parsing whole scope and not done, start again */
3969 	if (ret_type == 'T') {
3970 		aml_delref(&my_ret, "scope.loop");
3971 		while (scope->pos >= scope->end && scope != iscope) {
3972 			/* Pop intermediate scope */
3973 			scope = aml_popscope(scope);
3974 		}
3975 		if (scope->pos && scope->pos < scope->end)
3976 			goto start;
3977 	}
3978 
3979 	odp--;
3980 	dnprintf(50, ">>return [%s] %s %c %p\n", aml_nodename(scope->node),
3981 	    stype, ret_type, my_ret);
3982 
3983 	return my_ret;
3984 }
3985 
3986 int
3987 acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length)
3988 {
3989 	struct aml_scope *scope;
3990 	struct aml_value res;
3991 
3992 	aml_root.start = start;
3993 	memset(&res, 0, sizeof(res));
3994 	res.type = AML_OBJTYPE_SCOPE;
3995 	res.length = length;
3996 	res.v_buffer = start;
3997 
3998 	/* Push toplevel scope, parse AML */
3999 	aml_error = 0;
4000 	scope = aml_pushscope(NULL, &res, &aml_root, AMLOP_SCOPE);
4001 	aml_busy++;
4002 	aml_parse(scope, 'T', "TopLevel");
4003 	aml_busy--;
4004 	aml_popscope(scope);
4005 
4006 	if (aml_error) {
4007 		printf("error in acpi_parse_aml\n");
4008 		return -1;
4009 	}
4010 	return (0);
4011 }
4012 
4013 /*
4014  * @@@: External API
4015  *
4016  * evaluate an AML node
4017  * Returns a copy of the value in res  (must be freed by user)
4018  */
4019 int
4020 aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
4021     int argc, struct aml_value *argv, struct aml_value *res)
4022 {
4023 	struct aml_value *xres;
4024 
4025 	if (res)
4026 		memset(res, 0, sizeof(*res));
4027 	if (node == NULL || node->value == NULL)
4028 		return (ACPI_E_BADVALUE);
4029 	dnprintf(12,"EVALNODE: %s %d\n", aml_nodename(node), acpi_nalloc);
4030 
4031 	aml_error = 0;
4032 	xres = aml_eval(NULL, node->value, 't', argc, argv);
4033 	if (xres) {
4034 		if (res)
4035 			aml_copyvalue(res, xres);
4036 		if (xres != node->value)
4037 			aml_delref(&xres, "evalnode");
4038 	}
4039 	if (aml_error) {
4040 		printf("error evaluating: %s\n", aml_nodename(node));
4041 		return (-1);
4042 	}
4043 	return (0);
4044 }
4045 
4046 /*
4047  * evaluate an AML name
4048  * Returns a copy of the value in res  (must be freed by user)
4049  */
4050 int
4051 aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
4052     int argc, struct aml_value *argv, struct aml_value *res)
4053 {
4054 	parent = aml_searchname(parent, name);
4055 	return aml_evalnode(sc, parent, argc, argv, res);
4056 }
4057 
4058 /*
4059  * evaluate an AML integer object
4060  */
4061 int
4062 aml_evalinteger(struct acpi_softc *sc, struct aml_node *parent,
4063     const char *name, int argc, struct aml_value *argv, int64_t *ival)
4064 {
4065 	struct aml_value res;
4066 	int rc;
4067 
4068 	parent = aml_searchname(parent, name);
4069 	rc = aml_evalnode(sc, parent, argc, argv, &res);
4070 	if (rc == 0) {
4071 		*ival = aml_val2int(&res);
4072 		aml_freevalue(&res);
4073 	}
4074 	return rc;
4075 }
4076 
4077 /*
4078  * Search for an AML name in namespace.. root only
4079  */
4080 struct aml_node *
4081 aml_searchname(struct aml_node *root, const void *vname)
4082 {
4083 	char *name = (char *)vname;
4084 	char  nseg[AML_NAMESEG_LEN + 1];
4085 	int   i;
4086 
4087 	dnprintf(25,"Searchname: %s:%s = ", aml_nodename(root), vname);
4088 	if (*name == AMLOP_ROOTCHAR) {
4089 		root = &aml_root;
4090 		name++;
4091 	}
4092 	while (*name != 0) {
4093 		/* Ugh.. we can have short names here: append '_' */
4094 		strlcpy(nseg, "____", sizeof(nseg));
4095 		for (i=0; i < AML_NAMESEG_LEN && *name && *name != '.'; i++)
4096 			nseg[i] = *name++;
4097 		if (*name == '.')
4098 			name++;
4099 		root = __aml_search(root, nseg, 0);
4100 	}
4101 	dnprintf(25,"%p %s\n", root, aml_nodename(root));
4102 	return root;
4103 }
4104 
4105 /*
4106  * Search for relative name
4107  */
4108 struct aml_node *
4109 aml_searchrel(struct aml_node *root, const void *vname)
4110 {
4111 	struct aml_node *res;
4112 
4113 	while (root) {
4114 		res = aml_searchname(root, vname);
4115 		if (res != NULL)
4116 			return res;
4117 		root = root->parent;
4118 	}
4119 	return NULL;
4120 }
4121 
4122 #ifndef SMALL_KERNEL
4123 
4124 void
4125 acpi_getdevlist(struct acpi_devlist_head *list, struct aml_node *root,
4126     struct aml_value *pkg, int off)
4127 {
4128 	struct acpi_devlist *dl;
4129 	struct aml_node *node;
4130 	int idx;
4131 
4132 	for (idx=off; idx<pkg->length; idx++) {
4133 		node = aml_searchname(root, pkg->v_package[idx]->v_string);
4134 		if (node) {
4135 			dl = acpi_os_malloc(sizeof(*dl));
4136 			if (dl) {
4137 				dl->dev_node = node;
4138 				TAILQ_INSERT_TAIL(list, dl, dev_link);
4139 			}
4140 		}
4141 	}
4142 }
4143 
4144 void
4145 acpi_freedevlist(struct acpi_devlist_head *list)
4146 {
4147 	struct acpi_devlist *dl;
4148 
4149 	while ((dl = TAILQ_FIRST(list)) != NULL) {
4150 		TAILQ_REMOVE(list, dl, dev_link);
4151 		acpi_os_free(dl);
4152 	}
4153 }
4154 #endif /* SMALL_KERNEL */
4155