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