xref: /netbsd-src/usr.sbin/acpitools/aml/aml_parse.c (revision a41f6947a1dbcc459409ad07cbf69e8ce0688663)
1 /*	$NetBSD: aml_parse.c,v 1.6 2022/03/23 13:06:06 andvar Exp $	*/
2 
3 /*-
4  * Copyright (c) 1999 Doug Rabson
5  * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *	Id: aml_parse.c,v 1.32 2000/08/12 15:20:45 iwasaki Exp
30  *	$FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_parse.c,v 1.7 2001/10/23 14:54:15 takawata Exp $
31  */
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: aml_parse.c,v 1.6 2022/03/23 13:06:06 andvar Exp $");
34 
35 #include <sys/param.h>
36 
37 #include <acpi_common.h>
38 #include <aml/aml_amlmem.h>
39 #include <aml/aml_common.h>
40 #include <aml/aml_env.h>
41 #include <aml/aml_evalobj.h>
42 #include <aml/aml_name.h>
43 #include <aml/aml_obj.h>
44 #include <aml/aml_parse.h>
45 #include <aml/aml_status.h>
46 #include <aml/aml_store.h>
47 
48 #ifndef _KERNEL
49 #include <sys/stat.h>
50 #include <sys/mman.h>
51 
52 #include <assert.h>
53 #include <err.h>
54 #include <fcntl.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <unistd.h>
59 
60 #include "debug.h"
61 #else /* _KERNEL */
62 #include <sys/systm.h>
63 #include <sys/bus.h>
64 #include <dev/acpi/acpireg.h>
65 #include <dev/acpi/acpivar.h>
66 #ifndef ACPI_NO_OSDFUNC_INLINE
67 #include <machine/acpica_osd.h>
68 #endif
69 #endif /* !_KERNEL */
70 
71 static int		 findsetleftbit(int num);
72 static int		 findsetrightbit(int num);
73 static int		 frombcd(int num);
74 static int		 tobcd(int num);
75 
76 static u_int32_t	 aml_parse_pkglength(struct aml_environ *env);
77 static u_int8_t		 aml_parse_bytedata(struct aml_environ *env);
78 static u_int16_t	 aml_parse_worddata(struct aml_environ *env);
79 static u_int32_t	 aml_parse_dworddata(struct aml_environ *env);
80 static u_int8_t		*aml_parse_namestring(struct aml_environ *env);
81 static void		 aml_parse_defscope(struct aml_environ *env,
82 					    int indent);
83 static union aml_object	*aml_parse_defbuffer(struct aml_environ *env,
84 					     int indent);
85 static struct aml_name	*aml_parse_concat_number(struct aml_environ *env,
86 						 int num1, int indent);
87 static struct aml_name	*aml_parse_concat_buffer(struct aml_environ *env,
88 						 union aml_object *obj,
89 						 int indent);
90 static struct aml_name	*aml_parse_concat_string(struct aml_environ *env,
91 						 union aml_object *obj,
92 						 int indent);
93 static struct aml_name	*aml_parse_concatop(struct aml_environ *env,
94 					    int indent);
95 static union aml_object	*aml_parse_defpackage(struct aml_environ *env,
96 					      int indent);
97 static void		 aml_parse_defmethod(struct aml_environ *env,
98 					     int indent);
99 static void		 aml_parse_defopregion(struct aml_environ *env,
100 					       int indent);
101 static int		 aml_parse_field(struct aml_environ *env,
102 					 struct aml_field *template);
103 static void		 aml_parse_fieldlist(struct aml_environ *env,
104 					     struct aml_field *template,
105 					     int indent);
106 static void		 aml_parse_deffield(struct aml_environ *env,
107 					    int indent);
108 static void		 aml_parse_defindexfield(struct aml_environ *env,
109 						 int indent);
110 static void		 aml_parse_defbankfield(struct aml_environ *env,
111 						int indent);
112 static void		 aml_parse_defdevice(struct aml_environ *env,
113 					     int indent);
114 static void		 aml_parse_defprocessor(struct aml_environ *env,
115 						int indent);
116 static void		 aml_parse_defpowerres(struct aml_environ *env,
117 					       int indent);
118 static void		 aml_parse_defthermalzone(struct aml_environ *env,
119 						  int indent);
120 static struct aml_name	*aml_parse_defelse(struct aml_environ *env,
121 					   int indent, int num);
122 static struct aml_name	*aml_parse_defif(struct aml_environ *env,
123 					 int indent);
124 static struct aml_name	*aml_parse_defwhile(struct aml_environ *env,
125 					    int indent);
126 static void		 aml_parse_defmutex(struct aml_environ *env,
127 					    int indent);
128 static void		 aml_createfield_generic(struct aml_environ *env,
129 						 union aml_object *srcbuf,
130 						 int idx, int len,
131 						 char *newname);
132 static void		 aml_parse_defcreatefield(struct aml_environ *env,
133 						  int indent);
134 
135 static int
findsetleftbit(int num)136 findsetleftbit(int num)
137 {
138 	int	i, filter;
139 
140 	filter = 0;
141 	for (i = 0; i < 32; i++) {
142 		filter = filter >> 1;
143 		filter |= 1 << 31;
144 		if (filter & num) {
145 			break;
146 		}
147 	}
148 	i = (i == 32) ? 0 : i + 1;
149 	return (i);
150 }
151 
152 static int
findsetrightbit(int num)153 findsetrightbit(int num)
154 {
155 	int	i, filter;
156 
157 	filter = 0;
158 	for (i = 0; i < 32; i++) {
159 		filter = filter << 1;
160 		filter |= 1;
161 		if (filter & num) {
162 			break;
163 		}
164 	}
165 	i = (i == 32) ? 0 : i + 1;
166 	return (i);
167 }
168 
169 static int
frombcd(int num)170 frombcd(int num)
171 {
172 	int	res, factor;
173 
174 	res = 0;
175 	factor = 1;
176 	while (num != 0) {
177 		res += ((num & 0xf) * factor);
178 		num = num / 16;
179 		factor *= 10;
180 	}
181 	return (res);
182 }
183 
184 static int
tobcd(int num)185 tobcd(int num)
186 {
187 	int	res, factor;
188 
189 	res = 0;
190 	factor = 1;
191 	while (num != 0) {
192 		res += ((num % 10) * factor);
193 		num = num / 10;
194 		factor *= 16;
195 	}
196 	return (res);
197 }
198 
199 static u_int32_t
aml_parse_pkglength(struct aml_environ * env)200 aml_parse_pkglength(struct aml_environ *env)
201 {
202 	u_int8_t	*dp;
203 	u_int32_t	pkglength;
204 
205 	dp = env->dp;
206 	pkglength = *dp++;
207 	switch (pkglength >> 6) {
208 	case 0:
209 		break;
210 	case 1:
211 		pkglength = (pkglength & 0xf) + (dp[0] << 4);
212 		dp += 1;
213 		break;
214 	case 2:
215 		pkglength = (pkglength & 0xf) + (dp[0] << 4) + (dp[1] << 12);
216 		dp += 2;
217 		break;
218 	case 3:
219 		pkglength = (pkglength & 0xf)
220 		    + (dp[0] << 4) + (dp[1] << 12) + (dp[2] << 20);
221 		dp += 3;
222 		break;
223 	}
224 
225 	env->dp = dp;
226 	return (pkglength);
227 }
228 
229 static u_int8_t
aml_parse_bytedata(struct aml_environ * env)230 aml_parse_bytedata(struct aml_environ *env)
231 {
232 	u_int8_t	data;
233 
234 	data = env->dp[0];
235 	env->dp++;
236 	return (data);
237 }
238 
239 static u_int16_t
aml_parse_worddata(struct aml_environ * env)240 aml_parse_worddata(struct aml_environ *env)
241 {
242 	u_int16_t	data;
243 
244 	data = env->dp[0] + (env->dp[1] << 8);
245 	env->dp += 2;
246 	return (data);
247 }
248 
249 static u_int32_t
aml_parse_dworddata(struct aml_environ * env)250 aml_parse_dworddata(struct aml_environ *env)
251 {
252 	u_int32_t	data;
253 
254 	data = env->dp[0] + (env->dp[1] << 8) +
255 	    (env->dp[2] << 16) + (env->dp[3] << 24);
256 	env->dp += 4;
257 	return (data);
258 }
259 
260 static u_int8_t *
aml_parse_namestring(struct aml_environ * env)261 aml_parse_namestring(struct aml_environ *env)
262 {
263 	u_int8_t	*name;
264 	int		segcount;
265 
266 	name = env->dp;
267 	if (env->dp[0] == '\\')
268 		env->dp++;
269 	else if (env->dp[0] == '^')
270 		while (env->dp[0] == '^')
271 			env->dp++;
272 	if (env->dp[0] == 0x00)	/* NullName */
273 		env->dp++;
274 	else if (env->dp[0] == 0x2e)	/* DualNamePrefix */
275 		env->dp += 1 + 4 + 4;	/* NameSeg, NameSeg */
276 	else if (env->dp[0] == 0x2f) {	/* MultiNamePrefix */
277 		segcount = env->dp[1];
278 		env->dp += 1 + 1 + segcount * 4;	/* segcount * NameSeg */
279 	} else
280 		env->dp += 4;	/* NameSeg */
281 
282 	return (name);
283 }
284 
285 struct aml_name *
aml_parse_objectlist(struct aml_environ * env,int indent)286 aml_parse_objectlist(struct aml_environ *env, int indent)
287 {
288 	union	aml_object *obj;
289 
290 	obj = NULL;
291 	while (env->dp < env->end) {
292 		aml_print_indent(indent);
293 		obj = aml_eval_name(env, aml_parse_termobj(env, indent));
294 		AML_DEBUGPRINT("\n");
295 		if (env->stat == aml_stat_step) {
296 			AML_DEBUGGER(env, env);
297 			continue;
298 		}
299 		if (env->stat != aml_stat_none) {
300 			env->tempname.property = obj;
301 			return (&env->tempname);
302 		}
303 	}
304 	return (NULL);
305 }
306 
307 #define AML_CREATE_NAME(amlname, env, namestr, ret) do {		\
308 	amlname = aml_create_name(env, namestr);			\
309 	if (env->stat == aml_stat_panic)				\
310 		return ret;						\
311 } while(0)
312 
313 #define AML_COPY_OBJECT(dest, env, src, ret) do {			\
314 	dest = aml_copy_object(env, src);				\
315 	if (dest == NULL) {						\
316 		env->stat = aml_stat_panic;				\
317 		return ret;						\
318 	}								\
319 } while(0)
320 
321 #define AML_ALLOC_OBJECT(dest, env, type, ret) do {			\
322 	dest = aml_alloc_object(type, NULL);				\
323 	if (dest == NULL) {						\
324 		env->stat= aml_stat_panic;				\
325 		return ret;						\
326 	}								\
327 } while(0)
328 
329 static void
aml_parse_defscope(struct aml_environ * env,int indent)330 aml_parse_defscope(struct aml_environ *env, int indent)
331 {
332 	u_int8_t	*start, *end, *oend;
333 	u_int8_t	*name;
334 	u_int32_t	pkglength;
335 	struct	aml_name *oname;
336 
337 	start = env->dp;
338 	pkglength = aml_parse_pkglength(env);
339 
340 	AML_DEBUGPRINT("Scope(");
341 	name = aml_parse_namestring(env);
342 	aml_print_namestring(name);
343 	AML_DEBUGPRINT(") {\n");
344 	oname = env->curname;
345 	AML_CREATE_NAME(env->curname, env, name,);
346 	oend = env->end;
347 	env->end = end = start + pkglength;
348 	aml_parse_objectlist(env, indent + 1);
349 	aml_print_indent(indent);
350 	AML_DEBUGPRINT("}");
351 	AML_SYSASSERT(env->dp == env->end);
352 	env->dp = end;
353 	env->end = oend;
354 	env->curname = oname;
355 	env->stat = aml_stat_none;
356 }
357 
358 static union aml_object *
aml_parse_defbuffer(struct aml_environ * env,int indent)359 aml_parse_defbuffer(struct aml_environ *env, int indent)
360 {
361 	u_int8_t	*start;
362 	u_int8_t	*end;
363 	u_int8_t	*buffer;
364 	u_int32_t	pkglength;
365 	int	size1, size2, size;
366 	union	aml_object *obj;
367 
368 	start = env->dp;
369 	pkglength = aml_parse_pkglength(env);
370 	end = start + pkglength;
371 
372 	AML_DEBUGPRINT("Buffer(");
373 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
374 	size1 = aml_objtonum(env, obj);
375 	size2 = end - env->dp;
376 	size = (size1 < size2) ? size1 : size2;
377 	if (size1 > 0) {
378 		buffer = memman_alloc_flexsize(aml_memman, size1);
379 		if (buffer == NULL) {
380 			AML_DEBUGPRINT("NO MEMORY\n");
381 			env->stat = aml_stat_panic;
382 			return (NULL);
383 		}
384 		bzero(buffer, size1);
385 		bcopy(env->dp, buffer, size);
386 	} else {
387 		buffer = NULL;
388 	}
389 
390 	obj = &env->tempobject;
391 	obj->type = aml_t_buffer;
392 	obj->buffer.size = size1;
393 	obj->buffer.data = buffer;
394 	AML_DEBUGPRINT(") ");
395 	env->dp = end;
396 
397 	return (obj);
398 }
399 
400 static struct aml_name *
aml_parse_concat_number(struct aml_environ * env,int num1,int indent)401 aml_parse_concat_number(struct aml_environ *env, int num1, int indent)
402 {
403 	int	num2;
404 	struct	aml_name *destname;
405 	union	aml_object *obj;
406 
407 	num2 = aml_objtonum(env, aml_eval_name(env,
408 		aml_parse_termobj(env, indent)));
409 	AML_DEBUGPRINT(", ");
410 	destname = aml_parse_termobj(env, indent);
411 	AML_DEBUGPRINT(")");
412 	obj = &env->tempobject;
413 	obj->type = aml_t_buffer;
414 	obj->buffer.size = 2;
415 	obj->buffer.data = memman_alloc_flexsize(aml_memman, 2);
416 	if (obj->buffer.data == NULL) {
417 		env->stat = aml_stat_panic;
418 		return (NULL);
419 	}
420 	obj->buffer.data[0] = num1 & 0xff;
421 	obj->buffer.data[1] = num2 & 0xff;
422 	aml_store_to_name(env, obj, destname);
423 	return (&env->tempname);
424 }
425 
426 static struct aml_name *
aml_parse_concat_buffer(struct aml_environ * env,union aml_object * obj,int indent)427 aml_parse_concat_buffer(struct aml_environ *env, union aml_object *obj,
428     int indent)
429 {
430 	union	aml_object *tmpobj, *tmpobj2, *resobj;
431 	struct	aml_name *destname;
432 
433 	tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent));
434 	AML_DEBUGPRINT(", ");
435 	if (tmpobj->type != aml_t_buffer) {
436 		env->stat = aml_stat_panic;
437 		return (NULL);
438 	}
439 	AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL);
440 	destname = aml_parse_termobj(env, indent);
441 	AML_DEBUGPRINT(")");
442 	resobj = &env->tempobject;
443 	env->tempname.property = resobj;
444 	resobj->buffer.type = aml_t_buffer;
445 	resobj->buffer.size = tmpobj2->buffer.size + obj->buffer.size;
446 	if (resobj->buffer.size > 0) {
447 		resobj->buffer.data = memman_alloc_flexsize(aml_memman,
448 		    resobj->buffer.size);
449 		if (resobj->buffer.data == NULL) {
450 			env->stat = aml_stat_panic;
451 			return (NULL);
452 		}
453 		bcopy(obj->buffer.data, resobj->buffer.data, obj->buffer.size);
454 		bcopy(tmpobj2->buffer.data,
455 		    resobj->buffer.data + obj->buffer.size,
456 		    tmpobj2->buffer.size);
457 	} else {
458 		resobj->buffer.data = NULL;
459 	}
460 	aml_free_object(&tmpobj2);
461 	aml_store_to_name(env, resobj, destname);
462 	return (&env->tempname);
463 }
464 
465 static struct aml_name *
aml_parse_concat_string(struct aml_environ * env,union aml_object * obj,int indent)466 aml_parse_concat_string(struct aml_environ *env, union aml_object *obj,
467     int indent)
468 {
469 	int	len;
470 	union	aml_object *tmpobj, *tmpobj2, *resobj;
471 	struct	aml_name *destname;
472 
473 	tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent));
474 	AML_DEBUGPRINT(", ");
475 	if (tmpobj->type != aml_t_string) {
476 		env->stat = aml_stat_panic;
477 		return (NULL);
478 	}
479 	AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL);
480 	destname = aml_parse_termobj(env, indent);
481 	AML_DEBUGPRINT(")");
482 	resobj = &env->tempobject;
483 	env->tempname.property = resobj;
484 	resobj->type = aml_t_buffer;
485 	resobj->str.needfree = 1;
486 	len = strlen((const char *)obj->str.string) +
487 	    strlen((const char *)tmpobj2->str.string) + 1;
488 	if (len > 0) {
489 		resobj->str.string = memman_alloc_flexsize(aml_memman, len);
490 		if (resobj->str.string == NULL) {
491 			env->stat = aml_stat_panic;
492 			return (NULL);
493 		}
494 		strlcpy((char *)resobj->str.string, (const char *)obj->str.string, len);
495 		strlcat((char *)resobj->str.string, (const char *)tmpobj->str.string, len);
496 	} else {
497 		resobj->str.string = NULL;
498 	}
499 	aml_free_object(&tmpobj2);
500 	aml_store_to_name(env, resobj, destname);
501 	return (&env->tempname);
502 }
503 
504 static struct aml_name *
aml_parse_concatop(struct aml_environ * env,int indent)505 aml_parse_concatop(struct aml_environ *env, int indent)
506 {
507 	union	aml_object *obj, *tmpobj;
508 	struct	aml_name *aname;
509 
510 	AML_DEBUGPRINT("Concat(");
511 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
512 	AML_DEBUGPRINT(", ");
513 	switch (obj->type) {
514 	case aml_t_num:
515 		aname = aml_parse_concat_number(env, aml_objtonum(env, obj), indent);
516 		break;
517 
518 	case aml_t_buffer:
519 		/* obj may be temporal object */
520 		AML_COPY_OBJECT(tmpobj, env, obj, NULL);
521 		aname = aml_parse_concat_buffer(env, obj, indent);
522 		aml_free_object(&tmpobj);
523 		break;
524 
525 	case aml_t_string:
526 		/* obj may be temporal object */
527 		AML_COPY_OBJECT(tmpobj, env, obj, NULL);
528 		aname = aml_parse_concat_string(env, obj, indent);
529 		aml_free_object(&tmpobj);
530 		break;
531 
532 	default:
533 		env->stat = aml_stat_panic;
534 		aname = NULL;
535 		break;
536 	}
537 
538 	AML_DEBUGPRINT("\n");
539 	return (aname);
540 }
541 
542 static union aml_object *
aml_parse_defpackage(struct aml_environ * env,int indent)543 aml_parse_defpackage(struct aml_environ *env, int indent)
544 {
545 	u_int8_t	numelements;
546 	u_int8_t	*start;
547 	u_int32_t	pkglength;
548 	int		i;
549 	struct	aml_environ *copy;
550 	struct	aml_name *tmpname;
551 	union	aml_object *obj, **objects;
552 
553 	start = env->dp;
554 	pkglength = aml_parse_pkglength(env);
555 	numelements = aml_parse_bytedata(env);
556 	copy = memman_alloc(aml_memman, memid_aml_environ);
557 	if (copy == NULL) {
558 		env->stat = aml_stat_panic;
559 		return (NULL);
560 	}
561 	if (numelements > 0) {
562 		objects = memman_alloc_flexsize(aml_memman,
563 		    numelements * sizeof(union aml_object *));
564 		if (objects == NULL) {
565 			env->stat = aml_stat_panic;
566 			return (NULL);
567 		} else {
568 			bzero(objects, numelements * sizeof(union aml_object *));
569 		}
570 	} else {
571 		objects = NULL;
572 	}
573 
574 	*copy = *env;
575 	env->dp = copy->end = start + pkglength;
576 	AML_DEBUGPRINT("Package() {\n");
577 	i = 0;
578 	while ((copy->dp < copy->end) && (i < numelements)) {
579 		aml_print_indent(indent + 1);
580 		tmpname = aml_parse_termobj(copy, indent + 1);
581 
582 		if (tmpname != NULL) {
583 			objects[i] = aml_copy_object(copy, tmpname->property);
584 		}
585 		AML_DEBUGPRINT(",\n");
586 		i++;
587 	}
588 	aml_free_objectcontent(&copy->tempobject);
589 
590 	aml_print_indent(indent);
591 	AML_DEBUGPRINT("}");
592 	obj = &env->tempobject;
593 	obj->type = aml_t_package;
594 	obj->package.elements = numelements;
595 	obj->package.objects = objects;
596 
597 	memman_free(aml_memman, memid_aml_environ, copy);
598 	return (obj);
599 }
600 
601 static void
aml_parse_defmethod(struct aml_environ * env,int indent)602 aml_parse_defmethod(struct aml_environ *env, int indent)
603 {
604 	u_int8_t	flags;
605 	u_int8_t	*start;
606 	u_int32_t	pkglength;
607 	char	*name;
608 	struct	aml_environ *copy;
609 	struct	aml_method *meth;
610 	struct	aml_name *aname;
611 	union	aml_object *aobj;
612 
613 	start = env->dp;
614 	pkglength = aml_parse_pkglength(env);
615 	copy = memman_alloc(aml_memman, memid_aml_environ);
616 	if (copy == NULL) {
617 		env->stat = aml_stat_panic;
618 		return;
619 	}
620 	AML_DEBUGPRINT("Method(");
621 	name = (char *)aml_parse_namestring(env);
622 	aml_print_namestring((unsigned char *)name);
623 	AML_CREATE_NAME(aname, env, (unsigned char *)name,);
624 	if (aname->property != NULL) {
625 		env->stat = aml_stat_panic;
626 		AML_DEBUGPRINT("Already Defined \n");
627 		goto out;
628 	}
629 	AML_ALLOC_OBJECT(aobj, env, aml_t_method,);
630 	meth = &aobj->meth;
631 	aname->property = aobj;
632 	flags = *env->dp++;
633 
634 	if (flags) {
635 		AML_DEBUGPRINT(", %d", flags);
636 	}
637 	AML_DEBUGPRINT(") {\n");
638 	*copy = *env;
639 	meth->argnum = flags;
640 	meth->from = env->dp;
641 	meth->to = env->dp = copy->end = start + pkglength;
642 	aml_print_indent(indent);
643 	AML_DEBUGPRINT("}");
644 out:
645 	memman_free(aml_memman, memid_aml_environ, copy);
646 }
647 
648 static void
aml_parse_defopregion(struct aml_environ * env,int indent)649 aml_parse_defopregion(struct aml_environ *env, int indent)
650 {
651 	u_int8_t	*name;
652 	struct	aml_name *aname;
653 	struct	aml_opregion *opregion;
654 	union	aml_object *obj;
655 	const char	*regions[] = {
656 		"SystemMemory",
657 		"SystemIO",
658 		"PCI_Config",
659 		"EmbeddedControl",
660 		"SMBus",
661 	};
662 
663 	AML_DEBUGPRINT("OperationRegion(");
664 	/* Name */
665 	name = aml_parse_namestring(env);
666 	aml_print_namestring(name);
667 	AML_CREATE_NAME(aname, env, name,);
668 	if (aname->property != NULL) {
669 		env->stat = aml_stat_panic;
670 		AML_DEBUGPRINT("Already Defined \n");
671 		return;
672 	}
673 	AML_ALLOC_OBJECT(aname->property, env, aml_t_opregion,);
674 	opregion = &aname->property->opregion;
675 	opregion->space = *env->dp;
676 	AML_DEBUGPRINT(", %s, ", regions[*env->dp]);	/* Space */
677 	env->dp++;
678 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));	/* Offset */
679 	opregion->offset = aml_objtonum(env, obj);
680 	AML_DEBUGPRINT(", ");
681 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));	/* Length */
682 	opregion->length = aml_objtonum(env, obj);
683 	AML_DEBUGPRINT(")");
684 }
685 
686 static const char	*accessnames[] = {
687 	"AnyAcc",
688 	"ByteAcc",
689 	"WordAcc",
690 	"DWordAcc",
691 	"BlockAcc",
692 	"SMBSendRecvAcc",
693 	"SMBQuickAcc"
694 };
695 
696 static int
aml_parse_field(struct aml_environ * env,struct aml_field * template)697 aml_parse_field(struct aml_environ *env, struct aml_field *template)
698 {
699 	u_int8_t	*name;
700 	u_int8_t	acc, attribute;
701 	u_int32_t	width;
702 	struct	aml_name *aname;
703 	struct	aml_field *prop;
704 
705 	switch (*env->dp) {
706 	case '\\':
707 	case '^':
708 	case 'A'...'Z':
709 	case '_':
710 	case '.':
711 	case '/':
712 		name = aml_parse_namestring(env);
713 		width = aml_parse_pkglength(env);
714 		template->bitlen = width;
715 		aml_print_namestring(name);
716 		AML_CREATE_NAME(aname, env, name, 0);
717 		/* Alignment */
718 		if (width == 16) {
719 			template->bitoffset += 15;
720 			template->bitoffset &= (~15);
721 		}
722 		if (width == 32) {
723 			template->bitoffset += 31;
724 			template->bitoffset &= (~31);
725 		} else if ((width & 7) == 0) {
726 			template->bitoffset += 7;
727 			template->bitoffset &= (~7);
728 		} else if ((width > 32) && (width & 7) != 0) {
729 			AML_DEBUGPRINT("??? Can I treat it?\n");
730 		}
731 		if (aname->property != NULL) {
732 			env->stat = aml_stat_panic;
733 			AML_DEBUGPRINT("Already Defined \n");
734 			return (0);
735 		}
736 		AML_ALLOC_OBJECT(aname->property, env, aml_t_field, 0);
737 		prop = &aname->property->field;
738 		*prop = *template;
739 		template->bitoffset += width;
740 		AML_DEBUGPRINT(",\t%d", width);
741 		break;
742 	case 0x00:
743 		env->dp++;
744 		width = aml_parse_pkglength(env);
745 		template->bitoffset += width;
746 		AML_DEBUGPRINT("Offset(0x%x)", template->bitoffset);
747 		break;
748 	case 0x01:
749 		acc = env->dp[1];
750 		attribute = env->dp[2];
751 		env->dp += 3;
752 		AML_DEBUGPRINT("AccessAs(%s, %d)", accessnames[acc], attribute);
753 		template->bitoffset = attribute;
754 		template->flags = (template->flags | 0xf0) | acc;
755 		break;
756 	}
757 	return (template->bitoffset);
758 }
759 
760 static void
aml_parse_fieldlist(struct aml_environ * env,struct aml_field * template,int indent)761 aml_parse_fieldlist(struct aml_environ *env, struct aml_field *template,
762     int indent)
763 {
764 
765 	while (env->dp < env->end) {
766 		aml_print_indent(indent);
767 		(void)aml_parse_field(env, template);
768 		if (env->dp < env->end) {
769 			AML_DEBUGPRINT(",\n");
770 		} else {
771 			AML_DEBUGPRINT("\n");
772 		}
773 	}
774 }
775 
776 static void
aml_parse_deffield(struct aml_environ * env,int indent)777 aml_parse_deffield(struct aml_environ *env, int indent)
778 {
779 	u_int8_t	flags;
780 	u_int8_t	*start, *name;
781 	u_int32_t	pkglength;
782 	struct	aml_environ *copy;
783 	struct	aml_field fieldtemplate;
784 	static	const char *lockrules[] = {"NoLock", "Lock"};
785 	static	const char *updaterules[] = {"Preserve", "WriteAsOnes",
786 					     "WriteAsZeros", "*Error*"};
787 
788 	start = env->dp;
789 	pkglength = aml_parse_pkglength(env);
790 	copy = memman_alloc(aml_memman, memid_aml_environ);
791 	if (copy == NULL) {
792 		env->stat = aml_stat_panic;
793 		return;
794 	}
795 	AML_DEBUGPRINT("Field(");
796 	aml_print_namestring(name = aml_parse_namestring(env));
797 	fieldtemplate.type = aml_t_field;
798 	flags = aml_parse_bytedata(env);
799 	fieldtemplate.flags = flags;
800 
801 	*copy = *env;
802 	env->dp = copy->end = start + pkglength;
803 	fieldtemplate.bitoffset = 0;
804 	fieldtemplate.bitlen = 0;
805 	fieldtemplate.f.ftype = f_t_field;
806 	fieldtemplate.f.fld.regname = name;
807 	AML_DEBUGPRINT(", %s, %s, %s) {\n",
808 	    accessnames[flags & 0xf],
809 	    lockrules[(flags >> 4) & 1],
810 	    updaterules[(flags >> 5) & 3]);
811 	aml_parse_fieldlist(copy, &fieldtemplate, indent + 1);
812 	aml_print_indent(indent);
813 	AML_DEBUGPRINT("}");
814 	aml_free_objectcontent(&copy->tempobject);
815 
816 	AML_SYSASSERT(copy->dp == copy->end);
817 	memman_free(aml_memman, memid_aml_environ, copy);
818 }
819 
820 static void
aml_parse_defindexfield(struct aml_environ * env,int indent)821 aml_parse_defindexfield(struct aml_environ *env, int indent)
822 {
823 	u_int8_t	flags;
824 	u_int8_t	*start, *iname, *dname;
825 	u_int32_t	pkglength;
826 	struct	aml_environ *copy;
827 	struct	aml_field template;
828 	static	const char *lockrules[] = {"NoLock", "Lock"};
829 	static	const char *updaterules[] = {"Preserve", "WriteAsOnes",
830 					     "WriteAsZeros", "*Error*"};
831 
832 	start = env->dp;
833 	pkglength = aml_parse_pkglength(env);
834 	copy = memman_alloc(aml_memman, memid_aml_environ);
835 	if (copy == NULL) {
836 		env->stat = aml_stat_panic;
837 		return;
838 	}
839 	AML_DEBUGPRINT("IndexField(");
840 	aml_print_namestring(iname = aml_parse_namestring(env));	/* Name1 */
841 	AML_DEBUGPRINT(", ");
842 	aml_print_namestring(dname = aml_parse_namestring(env));	/* Name2 */
843 	template.type = aml_t_field;
844 	template.flags = flags = aml_parse_bytedata(env);
845 	template.bitoffset = 0;
846 	template.bitlen = 0;
847 	template.f.ftype = f_t_index;
848 	template.f.ifld.indexname = iname;
849 	template.f.ifld.dataname = dname;
850 	AML_DEBUGPRINT(", %s, %s, %s) {\n",
851 	    accessnames[flags & 0xf],
852 	    lockrules[(flags >> 4) & 1],
853 	    updaterules[(flags >> 5) & 3]);
854 	*copy = *env;
855 	env->dp = copy->end = start + pkglength;
856 	aml_parse_fieldlist(copy, &template, indent + 1);
857 	aml_print_indent(indent);
858 	AML_DEBUGPRINT("}");
859 	aml_free_objectcontent(&copy->tempobject);
860 
861 	AML_SYSASSERT(copy->dp == copy->end);
862 	memman_free(aml_memman, memid_aml_environ, copy);
863 }
864 
865 static void
aml_parse_defbankfield(struct aml_environ * env,int indent)866 aml_parse_defbankfield(struct aml_environ *env, int indent)
867 {
868 	u_int8_t	flags;
869 	u_int8_t	*start, *rname, *bname;
870 	u_int32_t	pkglength, bankvalue;
871 	struct	aml_environ *copy;
872 	struct	aml_field template;
873 	union	aml_object *obj;
874 	static	const char *lockrules[] = {"NoLock", "Lock"};
875 	static	const char *updaterules[] = {"Preserve", "WriteAsOnes",
876 					     "WriteAsZeros", "*Error*"};
877 
878 	start = env->dp;
879 	pkglength = aml_parse_pkglength(env);
880 	copy = memman_alloc(aml_memman, memid_aml_environ);
881 	if (copy == NULL) {
882 		env->stat = aml_stat_panic;
883 		return;
884 	}
885 	AML_DEBUGPRINT("BankField(");
886 	aml_print_namestring(rname = aml_parse_namestring(env));	/* Name1 */
887 	AML_DEBUGPRINT(", ");
888 	aml_print_namestring(bname = aml_parse_namestring(env));	/* Name2 */
889 	AML_DEBUGPRINT(", ");
890 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));	/* BankValue */
891 	bankvalue = aml_objtonum(env, obj);
892 	template.type = aml_t_field;
893 	template.flags = flags = aml_parse_bytedata(env);
894 	template.bitoffset = 0;
895 	template.bitlen = 0;
896 	template.f.ftype = f_t_bank;
897 	template.f.bfld.regname = rname;
898 	template.f.bfld.bankname = bname;
899 	template.f.bfld.bankvalue = bankvalue;
900 	*copy = *env;
901 	env->dp = copy->end = start + pkglength;
902 	AML_DEBUGPRINT(", %s, %s, %s) {\n",
903 	    accessnames[flags & 0xf],
904 	    lockrules[(flags >> 4) & 1],
905 	    updaterules[(flags >> 5) & 3]);
906 	aml_parse_fieldlist(copy, &template, indent + 1);
907 	aml_print_indent(indent);
908 	AML_DEBUGPRINT("}");
909 
910 	aml_free_objectcontent(&copy->tempobject);
911 	AML_SYSASSERT(copy->dp == copy->end);
912 	memman_free(aml_memman, memid_aml_environ, copy);
913 }
914 
915 static void
aml_parse_defdevice(struct aml_environ * env,int indent)916 aml_parse_defdevice(struct aml_environ *env, int indent)
917 {
918 	u_int8_t	*start;
919 	u_int8_t	*name;
920 	u_int32_t	pkglength;
921 	struct	aml_environ *copy;
922 
923 	start = env->dp;
924 	pkglength = aml_parse_pkglength(env);
925 	copy = memman_alloc(aml_memman, memid_aml_environ);
926 	if (copy == NULL) {
927 		env->stat = aml_stat_panic;
928 		return;
929 	}
930 	AML_DEBUGPRINT("Device(");
931 	name = aml_parse_namestring(env);
932 	aml_print_namestring(name);
933 	AML_DEBUGPRINT(") {\n");
934 	*copy = *env;
935 	AML_CREATE_NAME(copy->curname, env, name,);
936 	if (copy->curname->property != NULL) {
937 		env->stat = aml_stat_panic;
938 		AML_DEBUGPRINT("Already Defined \n");
939 		goto out;
940 	}
941 	AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_device,);
942 	env->dp = copy->end = start + pkglength;
943 	aml_parse_objectlist(copy, indent + 1);
944 	aml_print_indent(indent);
945 	AML_DEBUGPRINT("}");
946 	aml_free_objectcontent(&copy->tempobject);
947 
948 	AML_SYSASSERT(copy->dp == copy->end);
949 out:
950 	memman_free(aml_memman, memid_aml_environ, copy);
951 }
952 
953 static void
aml_parse_defprocessor(struct aml_environ * env,int indent)954 aml_parse_defprocessor(struct aml_environ *env, int indent)
955 {
956 	u_int8_t	*start;
957 	u_int8_t	*name;
958 	u_int32_t	pkglength;
959 	struct	aml_environ *copy;
960 	struct	aml_processor *proc;
961 	union	aml_object *obj;
962 
963 	start = env->dp;
964 	pkglength = aml_parse_pkglength(env);
965 	copy = memman_alloc(aml_memman, memid_aml_environ);
966 	if (copy == NULL) {
967 		env->stat = aml_stat_panic;
968 		return;
969 	}
970 	AML_ALLOC_OBJECT(obj, env, aml_t_processor,);
971 	proc = &obj->proc;
972 	AML_DEBUGPRINT("Processor(");
973 	name = aml_parse_namestring(env);
974 	aml_print_namestring(name);
975 	proc->id = aml_parse_bytedata(env);
976 	proc->addr = aml_parse_dworddata(env);
977 	proc->len = aml_parse_bytedata(env);
978 	AML_DEBUGPRINT(", %d, 0x%x, 0x%x) {\n", proc->id, proc->addr, proc->len);
979 	*copy = *env;
980 	AML_CREATE_NAME(copy->curname, env, name,);
981 	if (copy->curname->property != NULL) {
982 		env->stat = aml_stat_panic;
983 		AML_DEBUGPRINT("Already Defined \n");
984 		goto out;
985 	}
986 	copy->curname->property = obj;
987 	env->dp = copy->end = start + pkglength;
988 	aml_parse_objectlist(copy, indent + 1);
989 	aml_print_indent(indent);
990 	AML_DEBUGPRINT("}");
991 	aml_free_objectcontent(&copy->tempobject);
992 
993 	AML_SYSASSERT(copy->dp == copy->end);
994 out:
995 	memman_free(aml_memman, memid_aml_environ, copy);
996 }
997 
998 static void
aml_parse_defpowerres(struct aml_environ * env,int indent)999 aml_parse_defpowerres(struct aml_environ *env, int indent)
1000 {
1001 	u_int8_t	*start;
1002 	u_int8_t	*name;
1003 	u_int32_t	pkglength;
1004 	struct	aml_environ *copy;
1005 	struct	aml_powerres *pres;
1006 	union	aml_object *obj;
1007 
1008 	start = env->dp;
1009 	pkglength = aml_parse_pkglength(env);
1010 	copy = memman_alloc(aml_memman, memid_aml_environ);
1011 	if (copy == NULL) {
1012 		env->stat = aml_stat_panic;
1013 		return;
1014 	}
1015 	AML_DEBUGPRINT("PowerResource(");
1016 	AML_ALLOC_OBJECT(obj, env, aml_t_powerres,);
1017 	name = aml_parse_namestring(env);
1018 	aml_print_namestring(name);
1019 	pres = &obj->pres;
1020 	pres->level = aml_parse_bytedata(env);
1021 	pres->order = aml_parse_worddata(env);
1022 	AML_DEBUGPRINT(", %d, %d) {\n", pres->level, pres->order);
1023 	*copy = *env;
1024 	AML_CREATE_NAME(copy->curname, env, name,);
1025 	if (copy->curname->property != NULL) {
1026 		env->stat = aml_stat_panic;
1027 		AML_DEBUGPRINT("Already Defined \n");
1028 		goto out;
1029 	}
1030 	copy->curname->property = obj;
1031 	env->dp = copy->end = start + pkglength;
1032 
1033 	aml_parse_objectlist(copy, indent + 1);
1034 	aml_print_indent(indent);
1035 	AML_DEBUGPRINT("}");
1036 	aml_free_objectcontent(&copy->tempobject);
1037 
1038 	AML_SYSASSERT(copy->dp == copy->end);
1039 out:
1040 	memman_free(aml_memman, memid_aml_environ, copy);
1041 }
1042 
1043 static void
aml_parse_defthermalzone(struct aml_environ * env,int indent)1044 aml_parse_defthermalzone(struct aml_environ *env, int indent)
1045 {
1046 	u_int8_t	*start;
1047 	u_int8_t	*name;
1048 	u_int32_t	pkglength;
1049 	struct	aml_environ *copy;
1050 
1051 	start = env->dp;
1052 	pkglength = aml_parse_pkglength(env);
1053 	copy = memman_alloc(aml_memman, memid_aml_environ);
1054 	if (copy == NULL) {
1055 		env->stat = aml_stat_panic;
1056 		return;
1057 	}
1058 	AML_DEBUGPRINT("ThermalZone(");
1059 	name = aml_parse_namestring(env);
1060 	aml_print_namestring(name);
1061 	AML_DEBUGPRINT(") {\n");
1062 	*copy = *env;
1063 	AML_CREATE_NAME(copy->curname, env, name,);
1064 	if (copy->curname->property != NULL) {
1065 		env->stat = aml_stat_panic;
1066 		AML_DEBUGPRINT("Already Defined \n");
1067 		goto out;
1068 	}
1069 	AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_therm,);
1070 	env->dp = copy->end = start + pkglength;
1071 	aml_parse_objectlist(copy, indent + 1);
1072 	aml_print_indent(indent);
1073 	AML_DEBUGPRINT("}");
1074 	aml_free_objectcontent(&copy->tempobject);
1075 	AML_SYSASSERT(copy->dp == copy->end);
1076 out:
1077 	memman_free(aml_memman, memid_aml_environ, copy);
1078 }
1079 
1080 static struct aml_name *
aml_parse_defelse(struct aml_environ * env,int indent,int num)1081 aml_parse_defelse(struct aml_environ *env, int indent, int num)
1082 {
1083 	u_int8_t	*start, *end, *oend;
1084 	u_int32_t	pkglength;
1085 	struct	aml_name *aname;
1086 
1087 	start = env->dp;
1088 	pkglength = aml_parse_pkglength(env);
1089 	oend = env->end;
1090 	env->end = end = start + pkglength;
1091 	aname = NULL;
1092 
1093 	AML_DEBUGPRINT("Else {\n");
1094 	if (num == 0) {
1095 		aname = aml_parse_objectlist(env, indent + 1);
1096 		aml_print_indent(indent);
1097 	}
1098 	AML_DEBUGPRINT("}");
1099 
1100 	env->dp = end;
1101 	env->end = oend;
1102 	return (aname);
1103 }
1104 
1105 static struct aml_name *
aml_parse_defif(struct aml_environ * env,int indent)1106 aml_parse_defif(struct aml_environ *env, int indent)
1107 {
1108 	u_int8_t	*start, *end, *oend;
1109 	u_int32_t	pkglength;
1110 	int	num;
1111 	struct	aml_name *aname, *aname1;
1112 
1113 	start = env->dp;
1114 	pkglength = aml_parse_pkglength(env);
1115 	aname = NULL;
1116 
1117 	AML_DEBUGPRINT("If(");
1118 	num = aml_objtonum(env, aml_eval_name
1119 	    (env, aml_parse_termobj(env, indent)));
1120 	oend = env->end;
1121 	end = start + pkglength;
1122 	AML_DEBUGPRINT(")");
1123 	if (num) {
1124 		AML_DEBUGPRINT("{\n");
1125 		env->end = end;
1126 		aname = aml_parse_objectlist(env, indent + 1);
1127 		aml_print_indent(indent);
1128 		AML_DEBUGPRINT("}");
1129 	}
1130 	env->dp = end;
1131 	env->end = oend;
1132 	if ((end < oend) && *(env->dp) == 0xa1) {
1133 		env->dp++;
1134 		aname1 = aml_parse_defelse(env, indent, num);
1135 		aname = (num == 0) ? aname1 : aname;
1136 	}
1137 	return (aname);
1138 }
1139 
1140 static struct aml_name *
aml_parse_defwhile(struct aml_environ * env,int indent)1141 aml_parse_defwhile(struct aml_environ *env, int indent)
1142 {
1143 	u_int8_t	*start, *end, *oend;
1144 	u_int32_t	pkglength;
1145 	int	num;
1146 	struct	aml_name *aname;
1147 
1148 	start = env->dp;
1149 	pkglength = aml_parse_pkglength(env);
1150 	oend = env->end;
1151 	end = start + pkglength;
1152 	aname = NULL;
1153 	for (;;) {
1154 		env->dp = start;
1155 		aml_parse_pkglength(env);
1156 		AML_DEBUGPRINT("While(");
1157 		num = aml_objtonum(env, aml_eval_name
1158 		    (env, aml_parse_termobj(env, indent)));
1159 		AML_DEBUGPRINT(")");
1160 		if (num == 0) {
1161 			break;
1162 		}
1163 		AML_DEBUGPRINT(" {\n");
1164 		env->end = end;
1165 		aname = aml_parse_objectlist(env, indent + 1);
1166 		if (env->stat == aml_stat_step) {
1167 			AML_DEBUGGER(env, env);
1168 			continue;
1169 		}
1170 		if (env->stat != aml_stat_none)
1171 			break;
1172 		aml_print_indent(indent);
1173 		AML_DEBUGPRINT("}");
1174 	}
1175 	AML_DEBUGPRINT("\n");
1176 	env->dp = end;
1177 	env->end = oend;
1178 	if (env->stat == aml_stat_break) {
1179 		env->stat = aml_stat_none;
1180 		aname = NULL;
1181 	}
1182 	return (aname);
1183 }
1184 
1185 static void
aml_parse_defmutex(struct aml_environ * env,int indent)1186 aml_parse_defmutex(struct aml_environ *env, int indent)
1187 {
1188 	char	*name;
1189 	struct	aml_name *aname;
1190 	struct	aml_mutex *mut;
1191 
1192 	/* MutexOp */
1193 	AML_DEBUGPRINT("Mutex(");
1194 	name = (char *)aml_parse_namestring(env);
1195 	aml_print_namestring((unsigned char *)name);
1196 	AML_CREATE_NAME(aname, env, (unsigned char *)name,);
1197 	if (aname->property != NULL) {
1198 		env->stat = aml_stat_panic;
1199 		AML_DEBUGPRINT("Already Defined \n");
1200 		return;
1201 	}
1202 	AML_ALLOC_OBJECT(aname->property, env, aml_t_mutex,);
1203 	mut = &aname->property->mutex;
1204 	mut->level = *env->dp++;
1205 	STAILQ_INIT(&mut->queue);
1206 	AML_DEBUGPRINT(", %d)", mut->level);
1207 }
1208 
1209 static void
aml_createfield_generic(struct aml_environ * env,union aml_object * srcbuf,int idx,int len,char * newname)1210 aml_createfield_generic(struct aml_environ *env,
1211     union aml_object *srcbuf, int idx,
1212     int len, char *newname)
1213 {
1214 	struct	aml_bufferfield *field;
1215 	struct	aml_name *aname;
1216 
1217 	if (srcbuf == NULL || srcbuf->type != aml_t_buffer) {
1218 		AML_DEBUGPRINT("Not Buffer assigned,");
1219 		env->stat = aml_stat_panic;
1220 		return;
1221 	}
1222 	AML_CREATE_NAME(aname, env, (unsigned char *)newname,);
1223 	if (aname->property != NULL) {
1224 		env->stat = aml_stat_panic;
1225 		AML_DEBUGPRINT("Already Defined \n");
1226 		return;
1227 	}
1228 	AML_ALLOC_OBJECT(aname->property, env, aml_t_bufferfield,);
1229 	field = &aname->property->bfld;
1230 	field->bitoffset = idx;
1231 	field->bitlen = len;
1232 	field->origin = srcbuf->buffer.data;
1233 }
1234 
1235 static void
aml_parse_defcreatefield(struct aml_environ * env,int indent)1236 aml_parse_defcreatefield(struct aml_environ *env, int indent)
1237 {
1238 	int	idx, len;
1239 	char	*newname;
1240 	union	aml_object *obj, *srcbuf;
1241 
1242 	/* CreateFieldOp */
1243 	AML_DEBUGPRINT("CreateField(");
1244 	srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent));
1245 	if (srcbuf == &env->tempobject) {
1246 		AML_DEBUGPRINT("NONAMED BUFFER\n");
1247 		env->stat = aml_stat_panic;
1248 		return;
1249 	}
1250 	AML_DEBUGPRINT(", ");
1251 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
1252 	idx = aml_objtonum(env, obj);
1253 	AML_DEBUGPRINT(", ");
1254 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
1255 	len = aml_objtonum(env, obj);
1256 	AML_DEBUGPRINT(", ");
1257 	newname = (char *)aml_parse_namestring(env);
1258 	aml_print_namestring((unsigned char *)newname);
1259 	aml_createfield_generic(env, srcbuf, idx, len, newname);
1260 	AML_DEBUGPRINT(") ");
1261 }
1262 
1263 /*
1264  * Returns Named object or parser buffer. The object need not be free because
1265  * it returns preallocated buffer in env or Contain of named object.  If You
1266  * need to preserve object, create a copy and then store.  And The object
1267  * returned from this function is not valid after another call is
1268  * shared, tempolary buffer may be shared.
1269  */
1270 struct aml_name *
aml_parse_termobj(struct aml_environ * env,int indent)1271 aml_parse_termobj(struct aml_environ *env, int indent)
1272 {
1273 	u_int8_t	opcode;
1274 	u_int8_t	*name;
1275 	int	value;
1276 	int	num1, num2;
1277 	int	len;
1278 	int	match1, match2, i, pkgval, start;
1279 	int	widthindex, idx;
1280 	char	*newname;
1281 	struct	aml_name *aname;
1282 	struct	aml_name *destname1, *destname2;
1283 	struct	aml_name *tmpname, *srcname;
1284 	struct	aml_name *src;
1285 	union	aml_object *ret;
1286 	union	aml_object *tmpobj;
1287 	union	aml_object anum;
1288 	union	aml_object *objref;
1289 	union	aml_object *srcobj;
1290 	union	aml_object *obj;
1291 	union	aml_object *srcbuf;
1292 	static int	widthtbl[4] = {32, 16, 8, 1};
1293 	const char	*opname[4] = {"CreateDWordField", "CreateWordField",
1294 				      "CreateByteField", "CreateBitField"};
1295 
1296 	aname = &env->tempname;
1297 	ret = &env->tempobject;
1298 	anum.type = aml_t_num;
1299 	aname->property = ret;
1300 	aml_free_objectcontent(ret);
1301 	if (env->stat == aml_stat_panic) {
1302 		/*
1303 		 * If previously parser panic , parsing next instruction is
1304 		 * prohibited.
1305 		 */
1306 		return (NULL);
1307 	}
1308 	aname = NULL;
1309 	opcode = *env->dp++;
1310 	switch (opcode) {
1311 	case '\\':
1312 	case '^':
1313 	case 'A' ... 'Z':
1314 	case '_':
1315 	case '.':
1316 	case '/':
1317 		env->dp--;
1318 		ret->type = aml_t_namestr;
1319 		ret->nstr.dp = aml_parse_namestring(env);
1320 		aml_print_namestring(ret->nstr.dp);
1321 		aname = &env->tempname;
1322 		break;
1323 	case 0x0a:		/* BytePrefix */
1324 		ret->type = aml_t_num;
1325 		value = aml_parse_bytedata(env);
1326 		ret->num.number = value;
1327 		AML_DEBUGPRINT("0x%x", value);
1328 		aname = &env->tempname;
1329 		break;
1330 	case 0x0b:		/* WordPrefix */
1331 		ret->type = aml_t_num;
1332 		value = aml_parse_worddata(env);
1333 		ret->num.number = value;
1334 		AML_DEBUGPRINT("0x%x", value);
1335 		aname = &env->tempname;
1336 		break;
1337 	case 0x0c:		/* DWordPrefix */
1338 		ret->type = aml_t_num;
1339 		value = aml_parse_dworddata(env);
1340 		ret->num.number = value;
1341 		AML_DEBUGPRINT("0x%x", value);
1342 		aname = &env->tempname;
1343 		break;
1344 	case 0x0d:		/* StringPrefix */
1345 		ret->type = aml_t_string;
1346 		ret->str.string = env->dp;
1347 		len = strlen((const char *)env->dp);
1348 		ret->str.needfree = 0;
1349 		AML_DEBUGPRINT("\"%s\"", (const char *)ret->str.string);
1350 		env->dp += (len + 1);
1351 		aname = &env->tempname;
1352 		break;
1353 	case 0x00:		/* ZeroOp */
1354 		ret->type = aml_t_num;
1355 		ret->num.number = 0;
1356 		ret->num.constant = 1;
1357 		AML_DEBUGPRINT("Zero");
1358 		aname = &env->tempname;
1359 		break;
1360 	case 0x01:		/* OneOp */
1361 		ret->type = aml_t_num;
1362 		ret->num.number = 1;
1363 		ret->num.constant = 1;
1364 		AML_DEBUGPRINT("One");
1365 		aname = &env->tempname;
1366 		break;
1367 	case 0xff:		/* OnesOp */
1368 		ret->type = aml_t_num;
1369 		ret->num.number = 0xffffffff;
1370 		ret->num.constant = 1;
1371 		AML_DEBUGPRINT("Ones");
1372 		aname = &env->tempname;
1373 		break;
1374 	case 0x06:		/* AliasOp */
1375 		AML_DEBUGPRINT("Alias(");
1376 		tmpname = aml_parse_termobj(env, indent);
1377 		if (env->stat == aml_stat_panic) {
1378 			return (NULL);
1379 		}
1380 		if (tmpname->property == NULL ||
1381 		    tmpname->property->type != aml_t_namestr) {
1382 			env->stat = aml_stat_panic;
1383 			return (NULL);
1384 		}
1385 		/*
1386 		 * XXX if srcname is deleted after this object, what
1387 		 * shall I do?
1388 		 */
1389 		srcname = aml_search_name(env, tmpname->property->nstr.dp);
1390 		AML_DEBUGPRINT(", ");
1391 		name = aml_parse_namestring(env);
1392 		aml_print_namestring(name);
1393 		AML_CREATE_NAME(aname, env, name, 0);
1394 		if (aname->property != NULL) {
1395 			env->stat = aml_stat_panic;
1396 			AML_DEBUGPRINT("Already Defined \n");
1397 			aml_print_curname(aname);
1398 			return (NULL);
1399 		}
1400 		AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL);
1401 		objref = aname->property;
1402 		objref->objref.nameref = srcname;
1403 		objref->objref.ref = srcname->property;
1404 		objref->objref.offset = -1;
1405 		objref->objref.alias = 1;	/* Yes, this is an alias */
1406 		AML_DEBUGPRINT(")");
1407 		/* shut the interpreter up during the namespace initializing */
1408 		return (NULL);
1409 	case 0x08:		/* NameOp */
1410 		AML_DEBUGPRINT("Name(");
1411 		name = aml_parse_namestring(env);
1412 		aml_print_namestring(name);
1413 		AML_CREATE_NAME(aname, env, name, 0);
1414 		if (env->stat == aml_stat_panic) {
1415 			AML_DEBUGPRINT("Already Defined \n");
1416 			aml_print_curname(aname);
1417 			return (NULL);
1418 		}
1419 		AML_DEBUGPRINT(", ");
1420 		AML_COPY_OBJECT(aname->property, env,
1421 		    aml_eval_name(env,
1422 			aml_parse_termobj(env, indent)),
1423 		    NULL);
1424 		AML_DEBUGPRINT(")");
1425 		break;
1426 	case 0x10:		/* ScopeOp */
1427 		aml_parse_defscope(env, indent);
1428 		break;
1429 	case 0x11:		/* BufferOp */
1430 		aname = &env->tempname;
1431 		aname->property = aml_parse_defbuffer(env, indent);
1432 		break;
1433 	case 0x12:		/* PackageOp */
1434 		aname = &env->tempname;
1435 		aname->property = aml_parse_defpackage(env, indent);
1436 		break;
1437 	case 0x14:		/* MethodOp */
1438 		aml_parse_defmethod(env, indent);
1439 		break;
1440 	case 0x5b:		/* ExtOpPrefix */
1441 		opcode = *env->dp++;
1442 		switch (opcode) {
1443 		case 0x01:
1444 			aml_parse_defmutex(env, indent);
1445 			break;
1446 		case 0x02:	/* EventOp */
1447 			AML_DEBUGPRINT("Event(");
1448 			name = aml_parse_namestring(env);
1449 			aml_print_namestring(name);
1450 			AML_CREATE_NAME(aname, env, name, 0);
1451 			if (aname->property != NULL) {
1452 				env->stat = aml_stat_panic;
1453 				AML_DEBUGPRINT("Already Defined \n");
1454 				return (NULL);
1455 			}
1456 			AML_ALLOC_OBJECT(aname->property, env, aml_t_event, NULL);
1457 			AML_DEBUGPRINT(")");
1458 			return (NULL);
1459 			break;
1460 		case 0x12:	/* CondRefOfOp */
1461 			AML_DEBUGPRINT("CondRefOf(");
1462 			src = aml_parse_termobj(env, indent);
1463 			AML_DEBUGPRINT(", ");
1464 			if (src == &env->tempname || src == NULL) {
1465 				aml_parse_termobj(env, indent);
1466 				AML_DEBUGPRINT(")");
1467 				anum.num.number = 0xffffffff;
1468 				env->tempobject.num = anum.num;
1469 				aname = &env->tempname;
1470 				break;
1471 			}
1472 			AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL);
1473 			if (src->property == NULL ||
1474 			    src->property->type != aml_t_namestr) {
1475 				objref->objref.nameref = src;
1476 			} else {
1477 				objref->objref.nameref = aml_create_local_object();
1478 			}
1479 			objref->objref.ref = src->property;
1480 			objref->objref.offset = -1;	/* different from IndexOp */
1481 
1482 			destname1 = aml_parse_termobj(env, indent);
1483 			aml_store_to_name(env, objref, destname1);
1484 			anum.num.number = 0;
1485 			env->tempobject.num = anum.num;
1486 			aname = &env->tempname;
1487 			AML_DEBUGPRINT(")");
1488 			break;
1489 		case 0x13:
1490 			aml_parse_defcreatefield(env, indent);
1491 			break;
1492 		case 0x20:	/* LoadOp *//* XXX Not Impremented */
1493 			AML_DEBUGPRINT("Load(");
1494 			aml_parse_termobj(env, indent);
1495 			AML_DEBUGPRINT(", ");
1496 			aml_parse_termobj(env, indent);
1497 			AML_DEBUGPRINT(")");
1498 			break;
1499 		case 0x21:	/* StallOp */
1500 			AML_DEBUGPRINT("Stall(");
1501 			num1 = aml_objtonum(env, aml_eval_name(env,
1502 			    aml_parse_termobj(env, indent)));
1503 			AML_DEBUGPRINT(")");
1504 			AML_STALL(num1);
1505 			break;
1506 		case 0x22:	/* SleepOp */
1507 			AML_DEBUGPRINT("Sleep(");
1508 			num1 = aml_objtonum(env, aml_eval_name(env,
1509 			    aml_parse_termobj(env, indent)));
1510 			AML_SLEEP(0, num1);
1511 			AML_DEBUGPRINT(")");
1512 			break;
1513 		case 0x23:	/* AcquireOp *//* XXX Not yet */
1514 			AML_DEBUGPRINT("Acquire(");
1515 			aml_parse_termobj(env, indent);
1516 			AML_DEBUGPRINT(", 0x%x)", aml_parse_worddata(env));
1517 			break;
1518 		case 0x24:	/* SignalOp *//* XXX Not yet */
1519 			AML_DEBUGPRINT("Signal(");
1520 			aml_parse_termobj(env, indent);
1521 			AML_DEBUGPRINT(")");
1522 			break;
1523 		case 0x25:	/* WaitOp *//* XXX Not yet impremented */
1524 			AML_DEBUGPRINT("Wait(");
1525 			aml_parse_termobj(env, indent);
1526 			AML_DEBUGPRINT(", ");
1527 			aml_parse_termobj(env, indent);
1528 			AML_DEBUGPRINT(")");
1529 			break;
1530 		case 0x26:	/* ResetOp *//* XXX Not yet impremented */
1531 			AML_DEBUGPRINT("Reset(");
1532 			aml_parse_termobj(env, indent);
1533 			AML_DEBUGPRINT(")");
1534 			break;
1535 		case 0x27:	/* ReleaseOp *//* XXX Not yet impremented */
1536 			AML_DEBUGPRINT("Release(");
1537 			aml_parse_termobj(env, indent);
1538 			AML_DEBUGPRINT(")");
1539 			break;
1540 #define NUMOP2(opname, operation) do {					\
1541 	AML_DEBUGPRINT(opname);						\
1542 	AML_DEBUGPRINT("(");						\
1543 	num1 = aml_objtonum(env, aml_eval_name(env,			\
1544 	    aml_parse_termobj(env, indent)));				\
1545 	AML_DEBUGPRINT(", ");						\
1546 	anum.num.number = operation (num1);				\
1547 	destname1 = aml_parse_termobj(env, indent);			\
1548 	AML_DEBUGPRINT(")");						\
1549 	aml_store_to_name(env, &anum, destname1);			\
1550 	env->tempobject.num = anum.num;					\
1551 	env->tempname.property = &env->tempobject;			\
1552 	aname = &env->tempname;						\
1553 } while(0)
1554 
1555 		case 0x28:	/* FromBCDOp */
1556 			NUMOP2("FromBCD", frombcd);
1557 			break;
1558 		case 0x29:	/* ToBCDOp */
1559 			NUMOP2("ToBCD", tobcd);
1560 			break;
1561 		case 0x2a:	/* UnloadOp *//* XXX Not yet impremented */
1562 			AML_DEBUGPRINT("Unload(");
1563 			aml_parse_termobj(env, indent);
1564 			AML_DEBUGPRINT(")");
1565 			break;
1566 		case 0x30:
1567 			env->tempobject.type = aml_t_num;
1568 			env->tempobject.num.number = 0;
1569 			env->tempobject.num.constant = 1;
1570 			AML_DEBUGPRINT("Revision");
1571 			break;
1572 		case 0x31:
1573 			env->tempobject.type = aml_t_debug;
1574 			aname = &env->tempname;
1575 			AML_DEBUGPRINT("Debug");
1576 			break;
1577 		case 0x32:	/* FatalOp */
1578 			AML_DEBUGPRINT("Fatal(");
1579 			AML_DEBUGPRINT("0x%x, ", aml_parse_bytedata(env));
1580 			AML_DEBUGPRINT("0x%x, ", aml_parse_dworddata(env));
1581 			aml_parse_termobj(env, indent);
1582 			env->stat = aml_stat_panic;
1583 			AML_DEBUGPRINT(")");
1584 			break;
1585 		case 0x80:	/* OpRegionOp */
1586 			aml_parse_defopregion(env, indent);
1587 			break;
1588 		case 0x81:	/* FieldOp */
1589 			aml_parse_deffield(env, indent);
1590 			break;
1591 		case 0x82:	/* DeviceOp */
1592 			aml_parse_defdevice(env, indent);
1593 			break;
1594 		case 0x83:	/* ProcessorOp */
1595 			aml_parse_defprocessor(env, indent);
1596 			break;
1597 		case 0x84:	/* PowerResOp */
1598 			aml_parse_defpowerres(env, indent);
1599 			break;
1600 		case 0x85:	/* ThermalZoneOp */
1601 			aml_parse_defthermalzone(env, indent);
1602 			break;
1603 		case 0x86:	/* IndexFieldOp */
1604 			aml_parse_defindexfield(env, indent);
1605 			break;
1606 		case 0x87:	/* BankFieldOp */
1607 			aml_parse_defbankfield(env, indent);
1608 			break;
1609 		default:
1610 			AML_SYSERRX(1, "strange opcode 0x5b, 0x%x\n", opcode);
1611 			AML_SYSABORT();
1612 		}
1613 		break;
1614 	case 0x68 ... 0x6e:	/* ArgN */
1615 		AML_DEBUGPRINT("Arg%d", opcode - 0x68);
1616 		return (aml_local_stack_getArgX(NULL, opcode - 0x68));
1617 		break;
1618 	case 0x60 ... 0x67:
1619 		AML_DEBUGPRINT("Local%d", opcode - 0x60);
1620 		return (aml_local_stack_getLocalX(opcode - 0x60));
1621 		break;
1622 	case 0x70:		/* StoreOp */
1623 		AML_DEBUGPRINT("Store(");
1624 		aname = aml_create_local_object();
1625 		AML_COPY_OBJECT(tmpobj, env,
1626 		    aml_eval_name(env,	aml_parse_termobj(env, indent)), NULL);
1627 		aname->property = tmpobj;
1628 		AML_DEBUGPRINT(", ");
1629 		destname1 = aml_parse_termobj(env, indent);
1630 		AML_DEBUGPRINT(")");
1631 		/* XXX
1632 		 * temporary object may change during aml_store_to_name()
1633 		 * operation, so we make a copy of it on stack.
1634 		 */
1635 		if (destname1 == &env->tempname &&
1636 		    destname1->property == &env->tempobject) {
1637 			destname1 = aml_create_local_object();
1638 			AML_COPY_OBJECT(destname1->property, env,
1639 			    &env->tempobject, NULL);
1640 		}
1641 		aml_store_to_name(env, tmpobj, destname1);
1642 		if (env->stat == aml_stat_panic) {
1643 			AML_DEBUGPRINT("StoreOp failed");
1644 			return (NULL);
1645 		}
1646 		aname = aml_create_local_object();
1647 		AML_COPY_OBJECT(tmpobj, env, destname1->property, NULL);
1648 		aname->property = tmpobj;
1649 		if (tmpobj == NULL) {
1650 			printf("???");
1651 			break;
1652 		}
1653 		break;
1654 	case 0x71:		/* RefOfOp */
1655 		AML_DEBUGPRINT("RefOf(");
1656 		src = aml_parse_termobj(env, indent);
1657 		AML_DEBUGPRINT(")");
1658 
1659 		aname = aml_create_local_object();
1660 		AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL);
1661 		objref = aname->property;
1662 		if (src->property == NULL ||
1663 		    src->property->type != aml_t_namestr) {
1664 			objref->objref.nameref = src;
1665 		} else {
1666 			objref->objref.nameref = aml_create_local_object();
1667 		}
1668 		objref->objref.ref = src->property;
1669 		objref->objref.offset = -1;	/* different from IndexOp */
1670 		break;
1671 
1672 #define NUMOP3_2(opname, oparation, ope2) do {				\
1673 	AML_DEBUGPRINT(opname);						\
1674 	AML_DEBUGPRINT("(");						\
1675 	num1 = aml_objtonum(env, aml_eval_name(env,			\
1676 	    aml_parse_termobj(env, indent)));				\
1677 	AML_DEBUGPRINT(", ");						\
1678 	num2 = aml_objtonum(env, aml_eval_name(env,			\
1679 	    aml_parse_termobj(env, indent)));				\
1680 	AML_DEBUGPRINT(", ");						\
1681 	anum.num.number = ope2(num1 oparation num2);			\
1682 	destname1 = aml_parse_termobj(env, indent);			\
1683 	AML_DEBUGPRINT(")");						\
1684 	aml_store_to_name(env, &anum, destname1);			\
1685 	env->tempobject.num = anum.num;					\
1686 	env->tempname.property = &env->tempobject;			\
1687 	aname = &env->tempname;						\
1688 } while(0)
1689 
1690 #define NUMOP3(opname, operation)	NUMOP3_2(opname, operation, )
1691 #define NUMOPN3(opname, operation)	NUMOP3_2(opname, operation, ~)
1692 
1693 	case 0x72:		/* AddOp */
1694 		NUMOP3("Add", +);
1695 		break;
1696 	case 0x73:		/* ConcatOp  */
1697 		aname = aml_parse_concatop(env, indent);
1698 		break;
1699 	case 0x74:		/* SubtractOp */
1700 		NUMOP3("Subtract", -);
1701 		break;
1702 	case 0x75:		/* IncrementOp */
1703 		AML_DEBUGPRINT("Increment(");
1704 		aname = aml_parse_termobj(env, indent);
1705 		num1 = aml_objtonum(env, aml_eval_name(env, aname));
1706 		num1++;
1707 		anum.num.number = num1;
1708 		AML_DEBUGPRINT(")");
1709 		aml_store_to_name(env, &anum, aname);
1710 		aname = &env->tempname;
1711 		env->tempobject.num = anum.num;
1712 		break;
1713 	case 0x76:		/* DecrementOp */
1714 		AML_DEBUGPRINT("Decrement(");
1715 		aname = aml_parse_termobj(env, indent);
1716 		num1 = aml_objtonum(env, aml_eval_name(env, aname));
1717 		num1--;
1718 		anum.num.number = num1;
1719 		AML_DEBUGPRINT(")");
1720 		aml_store_to_name(env, &anum, aname);
1721 		aname = &env->tempname;
1722 		env->tempobject.num = anum.num;
1723 		break;
1724 	case 0x77:		/* MultiplyOp */
1725 		NUMOP3("Multiply", *);
1726 		break;
1727 	case 0x78:		/* DivideOp */
1728 		AML_DEBUGPRINT("Divide(");
1729 		num1 = aml_objtonum(env, aml_eval_name(env,
1730 		    aml_parse_termobj(env, indent)));
1731 		AML_DEBUGPRINT(", ");
1732 		num2 = aml_objtonum(env, aml_eval_name(env,
1733 		    aml_parse_termobj(env, indent)));
1734 		AML_DEBUGPRINT(", ");
1735 		anum.num.number = num1 % num2;
1736 		destname1 = aml_parse_termobj(env, indent);
1737 		aml_store_to_name(env, &anum, destname1);
1738 		AML_DEBUGPRINT(", ");
1739 		anum.num.number = num1 / num2;
1740 		destname2 = aml_parse_termobj(env, indent);
1741 		AML_DEBUGPRINT(")");
1742 		aml_store_to_name(env, &anum, destname2);
1743 		env->tempobject.num = anum.num;
1744 		aname = &env->tempname;
1745 		break;
1746 	case 0x79:		/* ShiftLeftOp */
1747 		NUMOP3("ShiftLeft", <<);
1748 		break;
1749 	case 0x7a:		/* ShiftRightOp */
1750 		NUMOP3("ShiftRight", >>);
1751 		break;
1752 	case 0x7b:		/* AndOp */
1753 		NUMOP3("And", &);
1754 		break;
1755 	case 0x7c:		/* NAndOp */
1756 		NUMOPN3("NAnd", &);
1757 		break;
1758 	case 0x7d:		/* OrOp */
1759 		NUMOP3("Or", |);
1760 		break;
1761 	case 0x7e:		/* NOrOp */
1762 		NUMOPN3("NOr", |);
1763 		break;
1764 	case 0x7f:		/* XOrOp */
1765 		NUMOP3("XOr", ^);
1766 		break;
1767 	case 0x80:		/* NotOp */
1768 		NUMOP2("Not", ~);
1769 		break;
1770 	case 0x81:		/* FindSetLeftBitOp */
1771 		NUMOP2("FindSetLeftBit", findsetleftbit);
1772 		break;
1773 	case 0x82:		/* FindSetRightBitOp */
1774 		NUMOP2("FindSetRightBit", findsetrightbit);
1775 		break;
1776 	case 0x83:		/* DerefOp */
1777 		AML_DEBUGPRINT("DerefOf(");
1778 		objref = aml_eval_name(env, aml_parse_termobj(env, indent));
1779 		AML_DEBUGPRINT(")");
1780 
1781 		if (objref->objref.ref == NULL) {
1782 			env->tempname.property = objref->objref.ref;
1783 			aname = &env->tempname;
1784 			break;
1785 		}
1786 		switch (objref->objref.ref->type) {
1787 		case aml_t_package:
1788 		case aml_t_buffer:
1789 			if (objref->objref.offset < 0) {
1790 				env->tempname.property = objref->objref.ref;
1791 			} else {
1792 				objref->objref.deref = 1;
1793 				env->tempname.property = objref;
1794 			}
1795 			break;
1796 		default:
1797 			env->tempname.property = objref->objref.ref;
1798 			break;
1799 		}
1800 
1801 		aname = &env->tempname;
1802 		break;
1803 	case 0x86:		/* NotifyOp *//* XXX Not yet impremented */
1804 		AML_DEBUGPRINT("Notify(");
1805 		aml_parse_termobj(env, indent);
1806 		AML_DEBUGPRINT(", ");
1807 		aml_parse_termobj(env, indent);
1808 		AML_DEBUGPRINT(")");
1809 		break;
1810 	case 0x87:		/* SizeOfOp */
1811 		AML_DEBUGPRINT("SizeOf(");
1812 		aname = aml_parse_termobj(env, indent);
1813 		tmpobj = aml_eval_name(env, aname);
1814 
1815 		AML_DEBUGPRINT(")");
1816 		num1 = 0;
1817 		switch (tmpobj->type) {
1818 		case aml_t_buffer:
1819 			num1 = tmpobj->buffer.size;
1820 			break;
1821 		case aml_t_string:
1822 			num1 = strlen((const char *)tmpobj->str.string);
1823 			break;
1824 		case aml_t_package:
1825 			num1 = tmpobj->package.elements;
1826 			break;
1827 		default:
1828 			AML_DEBUGPRINT("Args of SizeOf should be "
1829 				       "buffer/string/package only\n");
1830 			break;
1831 		}
1832 
1833 		anum.num.number = num1;
1834 		env->tempobject.num = anum.num;
1835 		aname = &env->tempname;
1836 		break;
1837 	case 0x88:		/* IndexOp */
1838 		AML_DEBUGPRINT("Index(");
1839 		srcobj = aml_eval_name(env, aml_parse_termobj(env, indent));
1840 		AML_DEBUGPRINT(", ");
1841 		num1 = aml_objtonum(env, aml_eval_name(env,
1842 		    aml_parse_termobj(env, indent)));
1843 		AML_DEBUGPRINT(", ");
1844 		destname1 = aml_parse_termobj(env, indent);
1845 		AML_DEBUGPRINT(")");
1846 		aname = aml_create_local_object();
1847 		switch (srcobj->type) {
1848 		case aml_t_package:
1849 		case aml_t_buffer:
1850 			AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL);
1851 			aname->property = objref;
1852 			objref->objref.ref = srcobj;
1853 			objref->objref.offset = num1;
1854 			objref->objref.deref = 0;
1855 			break;
1856 		default:
1857 			AML_DEBUGPRINT("Arg0 of Index should be either "
1858 				       "buffer or package\n");
1859 			return (aname);
1860 		}
1861 
1862 		aml_store_to_name(env, objref, destname1);
1863 		break;
1864 	case 0x89:		/* MatchOp *//* XXX Not yet Impremented */
1865 		AML_DEBUGPRINT("Match(");
1866 		AML_COPY_OBJECT(obj, env, aml_eval_name(env,
1867 		    aml_parse_termobj(env, indent)), NULL);
1868 		if (obj->type != aml_t_package) {
1869 			env->stat = aml_stat_panic;
1870 			return (NULL);
1871 		}
1872 		anum.num.number = 0xffffffff;
1873 		match1 = *env->dp;
1874 		AML_DEBUGPRINT(", %d", *env->dp);
1875 		env->dp++;
1876 		num1 = aml_objtonum(env, aml_eval_name(env,
1877 		    aml_parse_termobj(env, indent)));
1878 		match2 = *env->dp;
1879 		AML_DEBUGPRINT(", %d", *env->dp);
1880 		env->dp++;
1881 		num2 = aml_objtonum(env, aml_eval_name(env,
1882 		    aml_parse_termobj(env, indent)));
1883 		AML_DEBUGPRINT(", ");
1884 		start = aml_objtonum(env, aml_eval_name(env,
1885 		    aml_parse_termobj(env, indent)));
1886 
1887 #define MATCHOP(opnum, arg1, arg2)	((opnum == 0) ? (1) :		\
1888     (opnum == 1) ? ((arg1) == (arg2))	:				\
1889     (opnum == 2) ? ((arg1) <= (arg2))	:				\
1890     (opnum == 3) ? ((arg1) <  (arg2))	:				\
1891     (opnum == 4) ? ((arg1) >= (arg2))	:				\
1892     (opnum == 5) ? ((arg1) >  (arg2))	: 0 )
1893 
1894 		for (i = start; i < obj->package.elements; i++) {
1895 			pkgval = aml_objtonum(env, obj->package.objects[i]);
1896 			if (MATCHOP(match1, pkgval, num1) &&
1897 			    MATCHOP(match2, pkgval, num2)) {
1898 				anum.num.number = i;
1899 				break;
1900 			}
1901 		}
1902 		AML_DEBUGPRINT(")");
1903 		aml_free_object(&obj);
1904 		aname = &env->tempname;
1905 		env->tempname.property = &env->tempobject;
1906 		env->tempobject.num = anum.num;
1907 		break;
1908 #undef MATCHOP
1909 	case 0x8a ... 0x8d:	/* CreateDWordFieldOp */
1910 		widthindex = *(env->dp - 1) - 0x8a;
1911 		AML_DEBUGPRINT("%s(", opname[widthindex]);
1912 		srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent));
1913 		if (srcbuf == &env->tempobject) {
1914 			AML_DEBUGPRINT("NOT NAMEDBUF\n");
1915 			env->stat = aml_stat_panic;
1916 			return (NULL);
1917 		}
1918 		AML_DEBUGPRINT(", ");
1919 		idx = aml_objtonum(env, aml_eval_name(env,
1920 		    aml_parse_termobj(env, indent)));
1921 		if (widthindex != 3) {
1922 			idx *= 8;
1923 		}
1924 		AML_DEBUGPRINT(", ");
1925 		newname = (char *)aml_parse_namestring(env);
1926 		aml_print_namestring((unsigned char *)newname);
1927 		aml_createfield_generic(env, srcbuf, idx,
1928 		    widthtbl[widthindex], newname);
1929 		AML_DEBUGPRINT(")");
1930 		break;
1931 	case 0x8e:		/* ObjectTypeOp */
1932 		AML_DEBUGPRINT("ObjectType(");
1933 		aname = aml_parse_termobj(env, indent);
1934 		if (aname == NULL) {
1935 			env->tempobject.type = aml_t_num;
1936 			env->tempobject.num.number = aml_t_null;
1937 		} else {
1938 			env->tempobject.type = aml_t_num;
1939 			env->tempobject.num.number = aname->property->type;
1940 		}
1941 		aname = &env->tempname;
1942 		AML_DEBUGPRINT(")");
1943 		break;
1944 
1945 #define CMPOP(opname,operation) do {					\
1946 	AML_DEBUGPRINT(opname);						\
1947 	AML_DEBUGPRINT("(");						\
1948 	num1 = aml_objtonum(env, aml_eval_name(env,			\
1949 	    aml_parse_termobj(env, indent)));				\
1950 	AML_DEBUGPRINT(", ");						\
1951 	num2 = aml_objtonum(env, aml_eval_name(env,			\
1952 	    aml_parse_termobj(env, indent)));				\
1953 	aname = &env->tempname;						\
1954 	env->tempobject.type = aml_t_num;				\
1955 	env->tempobject.num.number = (num1 operation num2) ? 0xffffffff : 0;	\
1956 	aname->property = &env->tempobject;				\
1957 	AML_DEBUGPRINT(")");						\
1958 } while(0)
1959 
1960 	case 0x90:
1961 		CMPOP("LAnd", &&);
1962 		break;
1963 	case 0x91:
1964 		CMPOP("LOr", ||);
1965 		break;
1966 	case 0x92:
1967 		AML_DEBUGPRINT("LNot(");
1968 		num1 = aml_objtonum(env, aml_eval_name(env,
1969 		    aml_parse_termobj(env, indent)));
1970 		aname = &env->tempname;
1971 		env->tempobject.type = aml_t_num;
1972 		env->tempobject.num.number = (!num1) ? 0xffffffff : 0;
1973 		aname->property = &env->tempobject;
1974 		AML_DEBUGPRINT(")");
1975 		break;
1976 	case 0x93:
1977 		CMPOP("LEqual", ==);
1978 		break;
1979 	case 0x94:
1980 		CMPOP("LGreater", >);
1981 		break;
1982 	case 0x95:
1983 		CMPOP("LLess", <);
1984 		break;
1985 	case 0xa0:		/* IfOp */
1986 		aname = aml_parse_defif(env, indent);
1987 		break;
1988 #if 0
1989 
1990 	case 0xa1:		/* ElseOp should not be treated in Main parser
1991 				 * But If Op */
1992 		aml_parse_defelse(env, indent);
1993 		break;
1994 #endif
1995 	case 0xa2:		/* WhileOp */
1996 		aname = aml_parse_defwhile(env, indent);
1997 		break;
1998 	case 0xa3:		/* NoopOp */
1999 		AML_DEBUGPRINT("Noop");
2000 		break;
2001 	case 0xa5:		/* BreakOp */
2002 		AML_DEBUGPRINT("Break");
2003 		env->stat = aml_stat_break;
2004 		break;
2005 	case 0xa4:		/* ReturnOp */
2006 		AML_DEBUGPRINT("Return(");
2007 		AML_COPY_OBJECT(env->tempname.property, env, aml_eval_name(env,
2008 		    aml_parse_termobj(env, indent)), NULL);
2009 		aname = &env->tempname;
2010 		env->stat = aml_stat_return;
2011 		AML_DEBUGPRINT(")");
2012 		break;
2013 	case 0xcc:		/* BreakPointOp */
2014 		/* XXX Not Yet Impremented (Not need?) */
2015 		AML_DEBUGPRINT("BreakPoint");
2016 		break;
2017 	default:
2018 		AML_SYSERRX(1, "strange opcode 0x%x\n", opcode);
2019 		AML_SYSABORT();
2020 	}
2021 
2022 	return (aname);
2023 }
2024