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