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