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