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